バックグラウンドタスク#

結果や出力が不要なタスクを実行する必要がある場合、バックグラウンドタスクを使用して実行できます。バックグラウンドタスクは、ルートハンドラーなどとは並行して(つまり、バックグラウンドで)実行されます。バックグラウンドタスクは、完了に時間がかかるアクションを含む場合に非常に役立ちます。これにより、タスク自体が実行されている間にクライアントにレスポンスを送信できます。同様に、一部のタスクは、レスポンスが送信される前に完了する必要がなく、バックグラウンドで実行できます。

Quartのバックグラウンドタスクは、add_background_taskメソッドを使用して作成されます。

async def background_task():
    ...

@app.route('/jobs/', methods=['POST'])
async def create_job():
    app.add_background_task(background_task)
    return 'Success'

@app.before_serving
async def startup():
    app.add_background_task(background_task)

バックグラウンドタスクはアプリケーションコンテキストにアクセスできます。アプリのシャットダウン時に、タスクが完了するまで待機されます。タスクが設定されたBACKGROUND_TASK_SHUTDOWN_TIMEOUT内で完了しない場合、キャンセルされます。

注記 BACKGROUND_TASK_SHUTDOWN_TIMEOUTは、サーバーのシャットダウンス タイムアウトよりも短くする必要があります。

同期バックグラウンドタスクがサポートされており、別々のスレッドで実行されます。

警告

Quartはasyncioに基づいているため、単一の処理で実行され、IOの待機でブロックされたタスク間で切り替わります。タスクがIOを待機する必要がない場合、代わりにイベントループをブロックし、Quartが応答しなくなる可能性があります。さらに、タスクはサーバーと同じCPUリソースを消費するため、サーバーの速度が低下する可能性があります。

バックグラウンドタスクのテスト#

テストでバックグラウンドタスクが完了することを確認するには、test_appコンテキストマネージャーを使用します。これにより、テストを続行する前に、すべてのバックグラウンドタスクが完了するまで待機します。

async def test_tasks_complete():
    async with app.test_app():
        app.add_background_task(...)
    # Background task has completed here
    assert task_has_done_something

アプリをテストする際は、test_clientの使用はtest_appコンテキストブロック内で行う必要があります。

バックグラウンドタスクコルーチン関数は、アプリケーションコンテキストを作成して関数を待機することでテストできます。

async def test_background_task():
    async with app.app_context():
        await background_task()
    assert something_to_test