运行同步代码#
同步代码会阻塞事件循环,并降低运行它的 Quart 应用程序的性能。这是因为同步代码会阻塞它运行的任务,还会阻塞事件循环。出于这个原因,最好避免使用同步代码,优先使用异步版本。
不过,您可能需要使用一个同步的第三方库,因为它没有异步版本可以使用。在这种情况下,通常在线程池执行器中运行同步代码,这样它就不会阻塞事件循环,从而不会降低 Quart 应用程序的性能。这可能有点棘手,因此 Quart 提供了一些帮助程序来执行此操作。首先,任何同步路由都会在执行器中运行,例如:
@app.route("/")
def sync():
method = request.method
...
会导致 sync 函数在线程中运行。请注意,您仍然在 上下文 中,因此您仍然可以访问 request
、current_app
和其他全局变量。
以下功能接受同步函数,并将它们在线程中运行:
路由处理程序
端点处理程序
错误处理程序
上下文处理器
请求之前
WebSocket 之前
第一个请求之前
服务之前
请求之后
WebSocket 之后
服务之后
拆卸请求
拆卸 WebSocket
拆卸应用上下文
打开会话
创建空会话
保存会话
上下文用法#
虽然您可以在同步路由中访问 request
和其他全局变量,但您将无法等待协程函数。为了解决这个问题,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
和其他全局变量将无法访问。