异步 Python 服务器:启动时触发并忘记
Asynchronous Python server: fire and forget at startup
我正在编写一个必须处理异步任务的服务器。对于异步代码,我宁愿坚持使用 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 无法实现,正确的方法是什么?
见these docs,综上所述,
@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
我正在编写一个必须处理异步任务的服务器。对于异步代码,我宁愿坚持使用 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 无法实现,正确的方法是什么?
见these docs,综上所述,
@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