Skip to content

Commit ab44f6d

Browse files
author
Braden Pellett
committed
Remove drift from job scheduling
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()`.
1 parent 5aaed06 commit ab44f6d

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

schedule/__init__.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ def idle_seconds(self):
169169
:return: Number of seconds until
170170
:meth:`next_run <Scheduler.next_run>`.
171171
"""
172-
return (self.next_run - datetime.datetime.now()).total_seconds()
172+
seconds = (self.next_run - datetime.datetime.now()).total_seconds()
173+
return seconds if seconds > 0 else 0
173174

174175

175176
class Job(object):
@@ -483,8 +484,10 @@ def run(self):
483484
:return: The return value returned by the `job_func`
484485
"""
485486
logger.debug('Running job %s', self)
487+
self.last_run = (
488+
self.next_run if self.should_run else datetime.datetime.now()
489+
)
486490
ret = self.job_func()
487-
self.last_run = datetime.datetime.now()
488491
self._schedule_next_run()
489492
return ret
490493

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

505508
self.period = datetime.timedelta(**{self.unit: interval})
506-
self.next_run = datetime.datetime.now() + self.period
509+
self.next_run = (
510+
(self.last_run or datetime.datetime.now()) + self.period
511+
)
512+
# Move the next run to now if it already should have run, in order to
513+
# skip missed jobs.
514+
if self.should_run:
515+
self.next_run = datetime.datetime.now()
507516
if self.start_day is not None:
508517
if self.unit != 'weeks':
509518
raise ScheduleValueError('`unit` should be \'weeks\'')

0 commit comments

Comments
 (0)