I am using python's sched module to run a task periodically, and I think I have come across a bug.
I find that it relies on the time of the system on which the python script is run. For example, let's say that I want to run a task every 5 seconds. If I forward the system time, the scheduled task will run as expected. However, if I rewind the system time to, say 1 day, then the next scheduled task will run in 5 seconds + 1 day.
If you run the script below and then change your system time by a few days back, then you can reproduce the issue. The problem can be reproduced on Linux and Windows.
import sched
import time
import threading
period = 5
scheduler = sched.scheduler(time.time, time.sleep)
def check_scheduler():
print time.time()
scheduler.enter(period, 1, check_scheduler, ())
if __name__ == '__main__':
print time.time()
scheduler.enter(period, 1, check_scheduler, ())
thread = threading.Thread(target=scheduler.run)
thread.start()
thread.join()
exit(0)
Anyone has any python solution around this problem?
From the sched documentation:
class sched.scheduler(timefunc, delayfunc)
The scheduler class defines a generic interface to scheduling events. It needs two functions to actually deal with the “outside world” — timefunc should be callable without arguments, and return a number (the “time”, in any units whatsoever). The delayfunc function should be callable with one argument, compatible with the output of timefunc, and should delay that many time units. delayfunc will also be called with the argument 0 after each event is run to allow other threads an opportunity to run in multi-threaded applications.
The problem you have is that your code uses time.time()
as timefunc
, whose return value (when called without arguments) is the current system time and is thus affected by re-winding the system clock.
To make your code immune to system time changes you'd need to provide a timefunc
which doesn't depend on the system time, start/current timestamps, etc.
You can write your own function, for example one returning the number of seconds since your process is started, which you'd have to actually count in your code (i.e. don't compute it
based on timestamp deltas). The time.clock()
function might help, if it's based on CPU time counters, but I'm not sure if that's true or not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With