【发布时间】:2018-08-06 06:58:25
【问题描述】:
在 Flask 应用程序中运行异步事件循环的最佳方法是什么?
我的 main.py 看起来像这样:
if __name__ == '__main__':
try:
app.run(host='0.0.0.0', port=8000, debug=True)
except:
logging.critical('server: CRASHED: Got exception on main handler')
logging.critical(traceback.format_exc())
raise
要添加异步任务选项,我需要在运行 app 之前创建一个 event_loop,但即使停止应用运行,后台线程仍然挂起(在调试器中可观察到)
if __name__ == '__main__':
try:
app.event_loop = asyncio.get_event_loop()
app.run(host='0.0.0.0', port=8000, debug=True)
except:
logging.critical('server: CRASHED: Got exception on main handler')
logging.critical(traceback.format_exc())
raise
finally:
app.event_loop.stop()
app.event_loop.run_until_complete(app.event_loop.shutdown_asyncgens())
app.event_loop.close()
并使用以下内容创建异步任务:
def future_callback(fut):
if fut.exception():
logging.error(fut.exception())
def fire_and_forget(func, *args, **kwargs):
if callable(func):
future = app.event_loop.run_in_executor(None, func, *args, **kwargs)
future.add_done_callback(future_callback)
else:
raise TypeError('Task must be a callable')
我能找到的唯一解决方案是在finally 块的末尾添加exit(),但我认为它不是正确的解决方案。
【问题讨论】:
-
最好不要从 Flask 调用 asyncio 代码,对不起。
标签: python flask python-3.6 python-asyncio event-loop