Skip to content

Commit

Permalink
Remove drift from job scheduling
Browse files Browse the repository at this point in the history
Remove drift from job scheduling, by basing the next run time off the
last *scheduled* run time, instead of `datetime.datetime.now()`.

Additionally, `idle_seconds` is enforced to be non-negative, since it is
now possible for `next_run` to be just before `now()`.
  • Loading branch information
Braden Pellett committed Dec 14, 2020
1 parent 5aaed06 commit ab44f6d
Showing 1 changed file with 12 additions and 3 deletions.
15 changes: 12 additions & 3 deletions schedule/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ def idle_seconds(self):
:return: Number of seconds until
:meth:`next_run <Scheduler.next_run>`.
"""
return (self.next_run - datetime.datetime.now()).total_seconds()
seconds = (self.next_run - datetime.datetime.now()).total_seconds()
return seconds if seconds > 0 else 0


class Job(object):
Expand Down Expand Up @@ -483,8 +484,10 @@ def run(self):
:return: The return value returned by the `job_func`
"""
logger.debug('Running job %s', self)
self.last_run = (
self.next_run if self.should_run else datetime.datetime.now()
)
ret = self.job_func()
self.last_run = datetime.datetime.now()
self._schedule_next_run()
return ret

Expand All @@ -503,7 +506,13 @@ def _schedule_next_run(self):
interval = self.interval

self.period = datetime.timedelta(**{self.unit: interval})
self.next_run = datetime.datetime.now() + self.period
self.next_run = (
(self.last_run or datetime.datetime.now()) + self.period
)
# Move the next run to now if it already should have run, in order to
# skip missed jobs.
if self.should_run:
self.next_run = datetime.datetime.now()
if self.start_day is not None:
if self.unit != 'weeks':
raise ScheduleValueError('`unit` should be \'weeks\'')
Expand Down

0 comments on commit ab44f6d

Please sign in to comment.