ключевая проблема: asyncio.wait(aws,timeout=1,return_when=FIRST_COMPLETED)
Существует ли простой способ проверить, истекло ли время для возвращенной задачи?
Это расширенный вопрос.
Сцена такая:
- Общее количество сопрограмм неизвестно
- сервер допускает только 10 ссылок
- Сервер вернет, казалось бы, правильный результат (например, вернет неправильную страницу)
- Сервер иногда не возвращает никаких данных.
- Максимально возможный доступ ко всем данным
Итак, чтобы получить данные быстрее, мне нужно ограничить количество сопрограмм. Проверьте возвращенную страницу. И тайм-аут.
В настоящее время существует два простых метода.
1. аналогично потоку, используйте очередь для создания пула сопрограмм + 10 бесконечных циклов коро. Мне это не очень нравится. На самом деле этот метод работает очень быстро.
2. Я пытался использовать высокоуровневый API async python3.7, попытаться упростить структуру программы, используя while tasks
& 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
?