0

我正在编写一个必须处理异步任务的服务器。对于异步代码,我宁愿坚持使用 asyncio,所以我选择使用 Quart[-OpenAPI] 框架和 Uvicorn。

现在,我需要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 回答