Issue
I need to schedule a periodic function call in python (ie. called every minute), without blocking the event loop (I'm using Quart framework with asyncio).
Essentially need to submit work onto the event loop, with a timer, so that the webserver keeps serving incoming requests in the meantime and roughly every minute it calls my function.
I tried many ways, for instance:
def do_work():
print("WORK", flush=True)
async def schedule():
await asyncio.sleep(0)
print("scheduling")
loop = asyncio.get_running_loop()
t = loop.call_later(2, do_work)
print("scheduled")
asyncio.run(schedule())
But it either never gets executed (like the code above), or it blocks the webserver main event loop. For instance, with the code above I would expect (since it's done within asyncio.run
and schedule
awaits timer) that "scheduling" would be printed after (or during) the server setup, but that's not the case, it blocks.
Solution
You can use a background task that is started on startup,
async def schedule():
while True:
await asyncio.sleep(1)
await do_work()
@app.before_serving
async def startup():
app.add_background_task(schedule)
which will run schedule
for the lifetime of the app, being cancelled at shutdown.
Answered By - pgjones
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.