Skip to content

Asyncio schedulers break when the system is supended (put to sleep)

It seems that asyncio scheduler objects do not run at the correct time after suspending and waking the system. Consider the following example:

import asyncio
import datetime as dt

from scheduler.asyncio import Scheduler

async def print_current_time(): print(dt.datetime.now())

async def main():
    schedule = Scheduler()
    schedule.once(dt.timedelta(minutes=2), print_current_time)
    print(schedule)
    while schedule.jobs:
        await asyncio.sleep(1)

asyncio.run(main())

Try running it, then suspending the system for about 30 seconds to a minute, then waking the system back up again and waiting for jobs to complete.

What I expected was an output that printed out the due date of the job, to within a second or so. Instead, I got this:

tzinfo=None, #jobs=1

type     function / alias due at                 due in      attempts
-------- ---------------- ------------------- --------- -------------
ONCE     #_current_time() 2024-05-21 22:17:50   0:01:59           0/1

2024-05-21 22:18:32.577803

The job ran way after its due date, despite not being delayed by any prior jobs. However, if I rewrite this example with the ordinary scheduler then the output is much more as expected:

import time
import datetime as dt

from scheduler import Scheduler

def print_current_time(): print(dt.datetime.now())

schedule = Scheduler()
schedule.once(dt.timedelta(minutes=2), print_current_time)
print(schedule)
while schedule.jobs:
        schedule.exec_jobs()
        time.sleep(1)

output:

max_exec=inf, tzinfo=None, priority_function=linear_priority_function, #jobs=1

type     function / alias due at                 due in      attempts weight
-------- ---------------- ------------------- --------- ------------- ------
ONCE     #_current_time() 2024-05-21 22:21:00   0:01:59           0/1      1

2024-05-21 22:21:00.445851