我需要一个新的处理程序,它使用另一个现有的处理程序来同时处理多个请求:
async def process_multiple_queries(request):
init_request = request.clone()
body = await request.json()
for query in body["queries"]:
@asyncio.coroutine
def fake_json(self):
return query
# Replace request body on new fake json
R = init_request.clone()
R.json = fake_json.__get__(R, Request)
# Process request in the background task
asyncio.ensure_future(process_query(R))
async def process_query(request):
body = await request.json()
# ... Process body ...
return web.json_response({"result": "OK"})但是,所有定时任务的结果都等于最后一个任务的结果,即process_query中传入的所有请求的body只与最后一个请求的body相同。
但是如果我在asyncio.ensure_future(process_query(R))之后添加asyncio.sleep(5),所有的任务都会被正确地处理并产生不同的结果。
如何修复它?
发布于 2018-10-04 00:58:36
这是well-known Python的陷阱,闭包通过名称而不是值来捕获变量。因此,fake_json协程的所有实例都引用相同的query 变量,因此所有实例最终都引用其已知值。
要解决此问题,您需要更改定义:
@asyncio.coroutine
def fake_json(self):
return query到捕捉query价值的公式,例如:
@asyncio.coroutine
def fake_json(self, query=query):
return queryawait asyncio.sleep(5)很有帮助,因为它允许process_query在query的值发生变化之前运行到完成。使用await process_query(R)也会得到同样的效果。
与问题无关的两点:
@asyncio.coroutine装饰器
async def.fake_json不需要调用__get__来将self绑定到甚至不使用它的fake_json。您可以简单地分配R.json = fake_json.来定义一个不需要self的fake_json
https://stackoverflow.com/questions/52630461
复制相似问题