【发布时间】:2020-01-09 07:30:52
【问题描述】:
正如标题所说,我的用例是这样的:
我有一个 aiohttp 服务器,它接受来自客户端的请求,当我收到请求时,我为它生成一个唯一的请求 ID,然后我将 {req_id: req_pyaload} dict 发送给一些工作人员(工作人员不在 python 中,因此正在运行在另一个过程中),当工作人员完成工作时,我会返回响应并将它们放入结果字典中,如下所示:{req_id_1: res_1, req_id_2: res_2}。
然后我希望我的 aiohttp 服务器处理程序位于result dict 上方的await,因此当特定响应可用时(通过 req_id)它可以将其发送回来。
我构建了下面的示例代码以尝试模拟该过程,但在实现协程 async def fetch_correct_res(req_id) 时卡住了,该协程应该异步/非阻塞获取req_id 的正确响应。
import random
import asyncio
import shortuuid
n_tests = 1000
idxs = list(range(n_tests))
req_ids = []
for _ in range(n_tests):
req_ids.append(shortuuid.uuid())
res_dict = {}
async def fetch_correct_res(req_id):
pass
async def handler(req):
res = await fetch_correct_res(req)
assert req == res, "the correct res for the req should exactly be the req itself."
print("got correct res for req: {}".format(req))
async def randomly_put_res_to_res_dict():
for _ in range(n_tests):
random_idx = random.choice(idxs)
await asyncio.sleep(random_idx / 1000)
res_dict[req_ids[random_idx]] = req_ids[random_idx]
print("req: {} is back".format(req_ids[random_idx]))
所以:
是否可以使此解决方案发挥作用?怎么样?
如果上述解决方案不可行,对于这个使用 asyncio 的用例,正确的解决方案应该是什么?
非常感谢。
我现在能想到的唯一方法是:预先创建一些带有预先分配 id 的 asyncio.Queue,然后为每个传入的请求分配一个队列给它,所以处理程序只需 await这个队列,当响应返回时,我只将它放入这个预先分配的队列中,在请求完成后,我收集回队列以将其用于下一个传入请求。不是很优雅,但会解决问题。
【问题讨论】:
标签: python python-3.x async-await python-asyncio aiohttp