gpt4 book ai didi

python - 如何轻松找到已经超时的协程?

转载 作者:行者123 更新时间:2023-12-01 07:52:27 28 4
gpt4 key购买 nike

关键问题:asyncio.wait(aws,timeout=1,return_when=FIRST_COMPLETED) 有没有简单的方法来检查返回的任务是否超时?

这是一个扩展问题。

场景是这样的:

  • 协程总数未知
  • 服务器只允许 10 个链接
  • 服务器将返回看似正确的结果(例如返回不正确的页面)
  • 服务器有时不返回任何数据。
  • 对所有数据的最大可能访问权限

所以为了更快的获取数据,我需要限制协程的数量。检查返回的页面。并超时。

目前有两种简单的方法。
1.与线程类似,使用queue构建一个协程池+10个无限循环coro。我真的不喜欢它。事实上,这个方法效果非常快。
2.我尝试使用async python3.7的高级API,尝试简化程序的结构,使用whiletasks & asyncio.wait & return_when

在这里我遇到了如何找到协程超时的问题。

我构建了一个简单的演示:

import asyncio


async def test(delaytime):
print(f"begin {delaytime}")
await asyncio.sleep(delaytime )
print(f"finish {delaytime} ")

async def main():
# the number of tasks is unknow,range(10) is just a demo
allts = list(range(10))
ts = []
while len(ts)<5:
arg = allts.pop()
t = asyncio.create_task(test(arg))
t.arg = arg
ts.append(t)
while ts:
dones,pendings = await asyncio.wait(ts,timeout=2,return_when=asyncio.FIRST_COMPLETED)
for t in dones:
# if check t.result() is error , i can append ts again
print(t.arg,"is done")
ts.remove(t)
while len(ts)<5:
if len(allts):
arg = allts.pop()
t = asyncio.create_task(test(arg))
t.arg = arg
ts.append(t)
else:
break
# for t in pendings:
# # if can check t is timeout , i can append ts again
# pass

if __name__=="__main__":
asyncio.run(main())

经过调试,我知道return_when=asyncio.FIRST_COMPLETED,除了已完成的任务外,asyncio.wait返回的任务都处于待处理状态。
但是,我无法判断哪个任务超时。我考虑过使用 wait_for,但是 wait_for 没有 return_when 参数。

有没有简单的方法来确定超时任务以便重新加入ts

最佳答案

问题在于使用 wait(return_when=FIRST_COMPLETED) 的方法从根本上与 timeout 的使用不兼容。由于不同的任务在不同的时间启动,因此单个 timeout 参数显然无法应用于所有任务。如果您想使用 return_when=FIRST_COMPLETED,请将每个任务包装在 asyncio.wait_for 中:

t = asyncio.create_task(asyncio.wait_for(test(arg), 2))

然后,当任务完成后,可以使用t.exception()来测试是否超时,在这种情况下会返回asyncio.TimeoutError 。此检查只能在已完成任务中执行。

关于python - 如何轻松找到已经超时的协程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56136154/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com