同期コードの実行#

同期コードはイベントループをブロックし、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`などのグローバル変数にアクセスできません。