同期コードの実行#
同期コードはイベントループをブロックし、Quartアプリケーションのパフォーマンスを低下させます。これは、同期コードが実行されているタスクをブロックし、さらにイベントループをブロックするためです。このため、同期コードは避け、非同期バージョンを優先的に使用する必要があります。
ただし、非同期バージョンがないため、同期的なサードパーティライブラリを使用する必要がある場合があります。このような状況では、同期コードをスレッドプールエグゼキュータで実行するのが一般的です。これにより、イベントループがブロックされず、Quartアプリケーションのパフォーマンスが低下することがなくなります。これは少し難しい場合があるため、Quartはこれを行うためのヘルパーを提供しています。まず、同期ルートはすべてエグゼキュータで実行されます。つまり、
@app.route("/")
def sync():
method = request.method
...
は、`sync`関数をスレッドで実行させることになります。 コンテキスト内にいるため、`request`、`current_app`、その他のグローバル変数にアクセスできます。
以下の機能は同期関数を受け入れ、スレッドで実行します。
ルートハンドラ
エンドポイントハンドラ
エラーハンドラ
コンテキストプロセッサ
リクエスト前
WebSocket前
最初のリクエスト前
提供開始前
リクエスト後
WebSocket後
提供終了後
リクエストティアダウン
WebSocketティアダウン
アプリケーションコンテキストティアダウン
セッションを開く
nullセッションを作成
セッションを保存
コンテキストの使用#
同期ルートでは`request`などのグローバル変数にアクセスできますが、コルーチン関数を`await`することはできません。これを回避するために、Quartは次のように使用できる`run_sync()`を提供しています。
@app.route("/")
async def sync_within():
data = await request.get_json()
def sync_processor():
# does something with data
...
result = await run_sync(sync_processor)()
return result
これは、asyncioの`run_in_executor`関数を使用するのと似ています。
@app.route("/")
async def sync_within():
data = await request.get_json()
def sync_processor():
# does something with data
...
result = await asyncio.get_running_loop().run_in_executor(
None, sync_processor
)
return result
注記
`run_in_executor`関数は現在のコンテキストをコピーしませんが、`run_sync`メソッドはコピーします。このため、後者をお勧めします。コンテキストがコピーされていないと、`request`などのグローバル変数にアクセスできません。