在 Quart/asyncio 中安排定期函数调用
Scheduling periodic function call in Quart/asyncio
我需要在 python 中安排定期函数调用(即每分钟调用一次),而不阻塞事件循环(我正在使用 Quart framework with asyncio)。
基本上需要将工作提交到带有计时器的事件循环中,以便网络服务器同时继续为传入请求提供服务,并且大约每分钟它都会调用我的函数。
我尝试了很多方法,例如:
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())
但它要么永远不会执行(如上面的代码),要么阻止网络服务器主事件循环。例如,对于上面的代码,我希望(因为它是在 asyncio.run
和 schedule
等待计时器内完成的)“调度”将在服务器设置之后(或期间)打印,但事实并非如此,它会阻塞。
您可以使用 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)
这将 运行 schedule
在应用程序的生命周期内,在关闭时被取消。
我需要在 python 中安排定期函数调用(即每分钟调用一次),而不阻塞事件循环(我正在使用 Quart framework with asyncio)。
基本上需要将工作提交到带有计时器的事件循环中,以便网络服务器同时继续为传入请求提供服务,并且大约每分钟它都会调用我的函数。
我尝试了很多方法,例如:
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())
但它要么永远不会执行(如上面的代码),要么阻止网络服务器主事件循环。例如,对于上面的代码,我希望(因为它是在 asyncio.run
和 schedule
等待计时器内完成的)“调度”将在服务器设置之后(或期间)打印,但事实并非如此,它会阻塞。
您可以使用 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)
这将 运行 schedule
在应用程序的生命周期内,在关闭时被取消。