Commit 33d5f2fc authored by Patrik Dufresne's avatar Patrik Dufresne

Make the DeamonPlugin more robust

When the execution time of a plugin is miss configure, the plugin is not
running. With this commit, will default to daily execution at '23:00'
and pring an error message.
parent 2e08e2e7
Pipeline #206 passed with stages
in 29 minutes and 26 seconds
......@@ -34,9 +34,7 @@ from rdiffweb import rdw_spider_repos, page_main, librdiff
from rdiffweb.dispatch import poppath
from rdiffweb.i18n import ugettext as _
from rdiffweb.page_main import MainPage
from rdiffweb.rdw_plugin import IPreferencesPanelProvider, ITemplateFilterPlugin, \
IDeamonPlugin, JobPlugin
from rdiffweb.rdw_plugin import IPreferencesPanelProvider, ITemplateFilterPlugin, JobPlugin
_logger = logging.getLogger(__name__)
......
......@@ -35,9 +35,7 @@ from rdiffweb import rdw_spider_repos, page_main, librdiff
from rdiffweb.dispatch import poppath
from rdiffweb.i18n import ugettext as _
from rdiffweb.page_main import MainPage
from rdiffweb.rdw_plugin import IPreferencesPanelProvider, ITemplateFilterPlugin, \
IDeamonPlugin
from rdiffweb.rdw_plugin import IPreferencesPanelProvider, ITemplateFilterPlugin
_logger = logging.getLogger(__name__)
......
......@@ -31,14 +31,13 @@ import os
from pkg_resources import working_set, Environment
import pkg_resources
import sys
import time
from rdiffweb.dispatch import static
# Define logger for this module
logger = logging.getLogger(__name__)
PluginInfo = namedtuple(
'PluginInfo',
['name', 'version', 'author', 'description', 'path', 'enabled', 'url', 'copyright'])
......@@ -430,12 +429,11 @@ class IDeamonPlugin(IRdiffwebPlugin):
"""
CATEGORY = "Daemon"
@property
def deamon_frequency(self):
"""
Return the frequency of the deamon plugin in seconds.
"""
raise NotImplementedError("frequency is not implemented")
"""
Return the frequency in seconds of execution for this demaon plugin. Default: 60 seconds.
This value cannot be changed once the plugin is started.
"""
deamon_frequency = 60
def deamon_run(self):
"""
......@@ -451,35 +449,44 @@ class JobPlugin(IDeamonPlugin):
Sub class should implement `job_execution_time` and `job_run`.
"""
deamon_frequency = 300
job_execution_time = '23:00'
_next_execution_time = None
def deamon_run(self):
# Determine the next execution time.
if not self._next_execution_time:
self._next_execution_time = self._compute_next_execution_time()
# Check if task should be run.
now = datetime.datetime.now()
if now < self._next_execution_time:
return
self._wait()
# Run job.
try:
self.job_run()
finally:
self._next_execution_time = None
def _compute_next_execution_time(self):
def job_run(self):
"""
Sub-class should implement this function.
"""
raise NotImplementedError("job_run is not implemented")
def _wait(self):
"""
Sleep until time to execute the job.
"""
now = datetime.datetime.now()
t = self._get_next_execution_time()
time.sleep(t - now)
def _get_next_execution_time(self):
"""
Return a date time representing the next execution time.
"""
try:
time_str = self.job_execution_time
exec_time = datetime.datetime.strptime(time_str, '%H:%M')
except:
logger.error("invalid execution time [%s], check your config. Using default value.", self.job_execution_time)
exec_time = datetime.datetime.strptime("23:00", '%H:%M')
now = datetime.datetime.now()
time_str = self.job_execution_time
exec_time = datetime.datetime.strptime(time_str, '%H:%M')
exec_time = now.replace(hour=exec_time.hour, minute=exec_time.minute, second=0, microsecond=0)
if exec_time < now:
exec_time = exec_time.replace(day=exec_time.day + 1)
......
......@@ -23,10 +23,13 @@ Created on Jan 29, 2015
from __future__ import unicode_literals
import datetime
from mock.mock import Mock, MagicMock
import unittest
from rdiffweb import rdw_plugin
from rdiffweb.rdw_config import Configuration
from rdiffweb.rdw_plugin import PluginManager
from rdiffweb.rdw_plugin import PluginManager, JobPlugin
class PluginManagerTest(unittest.TestCase):
......@@ -51,6 +54,40 @@ class PluginManagerTest(unittest.TestCase):
self.assertEqual('GPLv3', plugin_info.copyright)
class JobPluginTest(unittest.TestCase):
def test_get_next_execution_time(self):
"""
Check JobPLugin execution time.
"""
p = JobPlugin()
p.job_execution_time = '2:00'
t = p._get_next_execution_time()
self.assertIsInstance(t, datetime.datetime)
def test_get_next_execution_time_invalid(self):
"""
Check JobPLugin execution time with invalid value.
"""
p = JobPlugin()
p.job_execution_time = '390'
t1 = p._get_next_execution_time()
p.job_execution_time = '23:00'
t2 = p._get_next_execution_time()
self.assertEqual(t1, t2)
def test_deamon_run(self):
"""
Check JobPlugin execution.
"""
rdw_plugin.time.sleep = MagicMock()
p = JobPlugin()
p.job_execution_time = '23:00'
p.job_run = lambda: "c"
p.deamon_run()
assert rdw_plugin.time.sleep.called
if __name__ == "__main__":
# import sys;sys.argv = ['', 'Test.testName']
unittest.main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment