Skip to content
Browse files

Removed DailyScheduler and added some backward-compat methods to Groc…

…Scheduler
  • Loading branch information...
1 parent accd2ca commit 2ecf114ef9d607caa6d4f8caa9fbcae5b24d1f1b Steve Johnson committed Aug 1, 2011
Showing with 75 additions and 79 deletions.
  1. +0 −1 test/config_test.py
  2. +0 −1 test/scheduler_test.py
  3. +15 −5 tron/config.py
  4. +60 −72 tron/scheduler.py
View
1 test/config_test.py
@@ -177,7 +177,6 @@ def test_job_schedule_attribute(self):
assert isinstance(self.job1.scheduler, scheduler.DailyScheduler)
assert_equal(self.job1.scheduler.start_time, datetime.time(hour=0, minute=30, second=0))
- assert self.job1.scheduler.wait_days
assert isinstance(self.job2.scheduler, scheduler.DailyScheduler)
assert_equal(self.job2.scheduler.start_time, datetime.time(hour=16, minute=30, second=0))
View
1 test/scheduler_test.py
@@ -102,7 +102,6 @@ def build_scheduler(self):
self.job = job.Job("Test Job", self.action)
self.job.node_pool = turtle.Turtle()
self.job.output_path = self.test_dir
- self.job.scheduler = self.scheduler
self.action.job = self.job
self.today = datetime.datetime(2011, 6, 1)
View
20 tron/config.py
@@ -641,7 +641,7 @@ def _apply(self):
class DailyScheduler(_ConfiguredObject):
yaml_tag = u'!DailyScheduler'
- actual_class = scheduler.DailyScheduler
+ actual_class = scheduler.GrocScheduler
def __init__(self, *args, **kwargs):
if len(args) > 0:
@@ -657,15 +657,25 @@ def __init__(self, *args, **kwargs):
def _apply(self):
sched = self._ref()
+ err_msg = ("Start time must be in string format HH:MM[:SS]. Seconds"
+ " are ignored but parsed so as to be backward-compatible.")
+
if hasattr(self, 'start_time'):
if not isinstance(self.start_time, basestring):
- raise ConfigError("Start time must be in string format HH:MM:SS")
+ raise ConfigError(err_msg)
+
+ # GrocScheduler will parse the values from the string.
+ # However, it only accepts HH:MM, not HH:MM:SS, so we truncate
+ # here if necessary.
+ hms = self.start_time.strip().split(':')
+
+ if len(hms) < 2:
+ raise ConfigError(err_msg)
- hour, minute, second = [int(val) for val in self.start_time.strip().split(':')]
- sched.start_time = datetime.time(hour=hour, minute=minute, second=second)
+ sched.timestr = ':'.join(hms)
if hasattr(self, 'days'):
- sched.wait_days = sched.get_daily_waits(self.days)
+ sched.parse_legacy_days(self.days)
class GrocScheduler(_ConfiguredObject):
View
132 tron/scheduler.py
@@ -21,8 +21,10 @@
for key, value in zip(day_list, range(7)):
CONVERT_DAYS_INT[key] = value
CONVERT_DAYS_INT[key.lower()] = value
+ CONVERT_DAYS_INT[key.upper()] = value
CONVERT_DAYS[key] = WEEK[value]
CONVERT_DAYS[key.lower()] = WEEK[value]
+ CONVERT_DAYS[key.upper()] = value
# Support January, Jan, january, jan, February, Feb...
CONVERT_MONTHS = dict() # month name/abbrev => {0 <= k <= 11}
@@ -91,71 +93,12 @@ def __ne__(self, other):
return not self == other
-class DailyScheduler(object):
- """The daily scheduler schedules one run per day"""
- def __init__(self, start_time=None, days=1):
- # What time of day does this thing start ? Default to 1 second after midnight
- self.start_time = start_time or datetime.time(hour=0, minute=0, second=1)
- self.wait_days = self.get_daily_waits(days)
-
- def get_daily_waits(self, days):
- """Computes how many days to wait till the next run from any day, starting with Monday.
- Example: MF runner: [4, 3, 2, 1, 3, 2, 1]
- """
- if isinstance(days, int):
- return [days for i in range(7)]
-
- week = [False for i in range(7)]
- for day in days:
- week[WEEK.index(CONVERT_DAYS[day[0:2].lower()])] = True
-
- count = week.index(True) + 1
- waits = deque()
-
- for val in reversed(week):
- waits.appendleft(count)
- count = 1 if val else count + 1
- return waits
-
- def next_runs(self, job):
- # Find the next time to run
- if job.runs:
- next_day = job.runs[0].run_time + datetime.timedelta(days=self.wait_days[job.runs[0].run_time.weekday()])
- else:
- next_day = timeutils.current_time() + datetime.timedelta(self.wait_days[timeutils.current_time().weekday()])
-
- run_time = next_day.replace(
- hour=self.start_time.hour,
- minute=self.start_time.minute,
- second=self.start_time.second,
- microsecond=0)
-
- job_runs = job.build_runs()
- for job_run in job_runs:
- job_run.set_run_time(run_time)
-
- return job_runs
-
- def job_setup(self, job):
- job.queueing = True
-
- def __str__(self):
- return "DAILY"
-
- def __eq__(self, other):
- return isinstance(other, DailyScheduler) and \
- self.wait_days == other.wait_days and self.start_time == other.start_time
-
- def __ne__(self, other):
- return not self == other
-
-
class GrocScheduler(object):
"""Wrapper around SpecificTimeSpecification in the Google App Engine cron library"""
def __init__(self, ordinals=None, weekdays=None, months=None, monthdays=None,
- timestr='00:00', timezone=None):
+ timestr='00:00', timezone=None, start_time=None):
"""Parameters:
- time - the time of day to run, as 'HH:MM'
+ timestr - the time of day to run, as 'HH:MM'
ordinals - first, second, third &c, as a set of integers in 1..5 to be
used with "1st <weekday>", etc.
monthdays - set of integers to be used with "<month> 3rd", etc.
@@ -165,26 +108,45 @@ def __init__(self, ordinals=None, weekdays=None, months=None, monthdays=None,
timezone - the optional timezone as a string for this specification.
Defaults to UTC - valid entries are things like Australia/Victoria
or PST8PDT.
+ start_time - Backward-compatible parameter for DailyScheduler
"""
self.ordinals = ordinals
self.weekdays = weekdays
self.months = months
self.monthdays = monthdays
self.timestr = timestr
self.timezone = timezone
-
- self.time_spec = None
+ self._start_time = start_time
+ self.string_repr = 'every day of month'
+
+ self._time_spec = None
+
+ @property
+ def time_spec(self):
+ if self._time_spec is None:
+ self._time_spec = SpecificTimeSpecification(ordinals=self.ordinals,
+ weekdays=self.weekdays,
+ months=self.months,
+ monthdays=self.monthdays,
+ timestr=self.timestr,
+ timezone=self.timezone)
+ return self._time_spec
def parse(self, scheduler_str):
- self.string_epr = scheduler_str
+ """Parse a schedule string."""
+ self.string_repr = scheduler_str
def parse_number(day):
return int(''.join(c for c in day if c.isdigit()))
m = GROC_SCHEDULE_RE.match(scheduler_str.lower())
if m.group('time') is None:
- self.timestr = '00:00'
+ if self._start_time is None:
+ self.timestr = '00:00'
+ else:
+ self.timestr = '%02d:%02d' % (self._start_time.hour,
+ self._start_time.minute)
else:
self.timestr = m.group('time')
@@ -207,12 +169,28 @@ def parse_number(day):
else:
self.months = set(CONVERT_MONTHS[mo] for mo in m.group('months').split(','))
- self.time_spec = SpecificTimeSpecification(ordinals=self.ordinals,
- weekdays=self.weekdays,
- months=self.months,
- monthdays=self.monthdays,
- timestr=self.timestr,
- timezone=self.timezone)
+ def parse_legacy_days(self, days):
+ """Parse a string that would have been passed to DailyScheduler"""
+ self.weekdays = set(CONVERT_DAYS_INT[d] for d in days)
+ if self.weekdays != set([0, 1, 2, 3, 4, 5, 6]):
+ self.string_repr = 'every %s of month' % ','.join(days)
+
+ def get_daily_waits(self, days):
+ """Backwards compatibility with DailyScheduler"""
+ self.parse_legacy_days(days)
+
+ def _get_start_time(self):
+ if self._start_time is None:
+ hms = [int(val) for val in self.timestr.strip().split(':')]
+ while len(hms) < 3:
+ hms.append(0)
+ hour, minute, second = hms
+ return datetime.time(hour=hour, minute=minute, second=second)
+
+ def _set_start_time(self, start_time):
+ self._start_time = start_time
+
+ start_time = property(_get_start_time, _set_start_time)
def next_runs(self, job):
# Find the next time to run
@@ -233,7 +211,12 @@ def job_setup(self, job):
job.queueing = True
def __str__(self):
- return self.string_repr
+ # Backward compatible string representation which also happens to be
+ # user-friendly
+ if self.string_repr == 'every day of month':
+ return 'DAILY'
+ else:
+ return self.string_repr
def __eq__(self, other):
return isinstance(other, GrocScheduler) and \
@@ -249,6 +232,11 @@ def __ne__(self, other):
return not self == other
+# GrocScheduler can pretend to be a DailyScheduler in order to be backdward-
+# compatible
+DailyScheduler = GrocScheduler
+
+
class IntervalScheduler(object):
"""The interval scheduler runs a job (to success) based on a configured interval
"""

0 comments on commit 2ecf114

Please sign in to comment.
Something went wrong with that request. Please try again.