0

非同期タスクを処理する必要があるサーバーを作成しています。非同期コードでは asyncio に固執したいので、Uvicorn で Quart[-OpenAPI] フレームワークを使用することにしました。

ここで、サーバーの起動時にタスク (master.resume()以下のコード) を実行する必要があります。サーバーが完了するのを待たずに、つまり、起動して忘れます。

このタスクを待つことができないため、asyncio でも可能かどうかはわかりませんが、そうしないとcoroutine X was never awaitedエラーが発生します。この回答でloop.run_until_complete()提案されているように使用すると、タスクが完了するまでサーバーがブロックされます。

これが私が持っているコードのスケルトンです:

import asyncio
from quart_openapi import Pint, Resource


app = Pint(__name__, title="Test")


class Master:
    ...

    async def resume():
        await coro()

    async def handle_get()
        ...


@app.route("/test")
class TestResource(Resource):
    async def get(self):
        print("Received get")
        asyncio.create_task(master.handle_get())

        return {"message": "Request received"}


master = Master()

# How do I fire & forget master.resume()?
master.resume()  # <== This throws "RuntimeWarning: coroutine 'Master.resume' was never awaited"
asyncio.get_event_loop().run_until_complete(master.resume())  # <== This prevents the server from starting

これを asyncio/Quart で達成できない場合、適切な方法は何でしょうか?

4

1 に答える 1

1

要約すると、 これらのドキュメントを参照してください。

@app.before_serving
async def startup():
    asyncio.ensure_future(master.resume())

ただし、シャットダウン時にキャンセルできるように、タスクを保留します。

@app.before_serving
async def startup():
    app.background_task = asyncio.ensure_future(master.resume())

@app.after_serving
async def shutdown():
    app.background_task.cancel()  # Or something similar
于 2020-04-24T18:05:50.393 に答える