如何调整Tornado定时调度逻辑适配async异步函数的周期性调用?
适配方案
不需要将schedule_next_sync改为异步函数,也不要强行同步执行异步的s(c)(会阻塞Tornado的IO事件循环,导致其他服务逻辑卡住),只需要调整回调层适配异步调用即可:
修改后完整代码
import datetime import tornado.ioloop # 假设c是全局可访问的上下文变量,如有需要可自行调整传参逻辑 def schedule_next_sync(): t = datetime.datetime.now() # 计算下一日0点的执行时间,补全时分秒毫秒避免受当前时间精度影响 t = t.replace(hour=0, minute=0, second=0, microsecond=0) + datetime.timedelta(hours=24) # 新增异步wrapper层,用于执行异步s函数 async def async_wrapper(): try: await s(c) except Exception as e: # 自行补充异常日志打印逻辑,避免报错吞信息 print(f"同步任务执行异常: {repr(e)}") finally: # 无论执行成功失败都注册下一次定时,避免任务中断 schedule_next_sync() # 超时触发的同步wrapper,负责把异步任务提交给IOloop调度 def wrapper(): tornado.ioloop.IOLoop.current().add_callback(async_wrapper) tornado.ioloop.IOLoop.current().add_timeout(datetime.datetime.timestamp(t), wrapper)
说明
schedule_next_sync本身只有时间计算、回调注册的同步逻辑,没有IO操作,完全不需要改成异步函数,首次启动直接调用schedule_next_sync()即可,不需要加await。- 不要用
asyncio.run/run_until_complete之类的方法强行同步执行s(c),会直接阻塞整个IO事件循环,违背Tornado的异步设计原则。 - 加了异常捕获逻辑是避免
s(c)执行报错导致下一次定时没有被注册,最终任务中断的问题,你可以根据自己的需求调整异常处理逻辑。
内容的提问来源于stack exchange,提问作者ca9163d9
相关产品推荐
相关产品推荐

