自定义事件循环#

自定义事件循环通常是为了将 Quart 与其他库一起使用,同时确保两者使用相同的循环。最佳实践是在 Quart 创建的循环中创建/初始化第三方库,使用启动和关闭before_serving函数,如下所示:

@app.before_serving
async def startup():
    loop = asyncio.get_event_loop()
    app.smtp_server = loop.create_server(aiosmtpd.smtp.SMTP, port=1025)
    loop.create_task(app.smtp_server)

@app.after_serving
async def shutdown():
    app.smtp_server.close()

不要遵循此模式,这通常在示例中看到,因为它为 ThirdParty 创建了一个与 Quart 循环分开的循环:

loop = asyncio.get_event_loop()
third_party = ThirdParty(loop)
app.run()  # A new loop is created by default

控制事件循环#

运行 Quart 的 ASGI 服务器拥有 Quart 运行其中的事件循环,默认情况下该服务器是 Hypercorn。 Quart 和 Hypercorn 都允许指定循环,Quart 在开发中的快捷方式是将循环传递给 app.run 方法:

loop = asyncio.get_event_loop()
third_party = ThirdParty(loop)
app.run(loop=loop)

或者使用 app.run_task 方法:

loop = asyncio.get_event_loop()
third_party = ThirdParty(loop)
loop.run_until_complete(app.run_task())

Hypercorn(生产)解决方案是利用Hypercorn API执行以下操作:

from hypercorn.asyncio import serve
from hypercorn.config import Config
...
loop = asyncio.get_event_loop()
third_party = ThirdParty(loop)
loop.run_until_complete(serve(app, Config()))
# or even
await serve(app, config)