イベントループをカスタマイズする#
イベントループをカスタマイズすると、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()
例に一般的に見られるこのパターンには従わないでください。このパターンでは、サードパーティのために Quart ループとは別の新しいループが作成されます。
loop = asyncio.get_event_loop()
third_party = ThirdParty(loop)
app.run() # A new loop is created by default
イベントループを制御する#
Quart を実行しているイベントループを所有するのは、Quart を実行している ASGI サーバーです。デフォルトではそのサーバーは 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)