Flask 应用程序中的 asyncio event_loop

Mug*_*gen 7 python event-loop flask python-asyncio python-3.6

在 Flask 应用程序中运行 asyncio 事件循环的最佳方法是什么?

我的 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
Run Code Online (Sandbox Code Playgroud)

要添加异步任务的选项,我需要event_loop在运行之前创建一个app,但即使停止应用程序运行时,后台线程仍然挂起(在调试器中可观察到)

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()
Run Code Online (Sandbox Code Playgroud)

并使用以下内容创建异步任务:

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')
Run Code Online (Sandbox Code Playgroud)

我能找到的唯一解决方案是exit()finally块的末尾添加,但我认为这不是正确的解决方案。

Mug*_*gen 0

最终我找到的最好的解决方案是托管我的 Flask 应用程序,在其中uwsgi可以使用mules异步spooler任务

https://uwsgi-docs.readthedocs.io/en/latest/Spooler.html

https://uwsgi-docs.readthedocs.io/en/latest/Mules.html