Мне было интересно, если это правильный способ сделать это в aiohttp
Ваш код достаточно идиоматичен. На верхнем уровне вы можете опустить asyncio.ensure_future
и просто позвонить asyncio.run(run(possible_answers))
.
Как отменить обработку при выполнении условия (кода состояния)?
Вы можете использовать событие или будущий объект и ждать его вместо использования gather
. Как вы, вероятно, знаете, gather
не требуется для запуска сопрограмм (они запускаются, как запланировано с create_task
), его явная цель - дождаться завершения всех сопрограмм. Синхронизация на основе Event
может выглядеть так:
async def bound_fetch(sem, session, answer, done):
# generating url, headers and json ...
async with sem, session.post(url=url, json=json, headers=headers) as response:
if response.status == 200:
done.set()
done.run_answer = json['answer']
async def run(words):
sem = asyncio.Semaphore(3)
done = asyncio.Event()
async with aiohttp.ClientSession() as session:
tasks = []
for word in words:
tasks.append(asyncio.create_task(bound_fetch(
sem=sem, session=session, answer=''.join(word), done=done)))
print("Generated %d possible answers. Checking %s" % (len(words), base_url))
await done.wait()
print('Right answer found: %s' % done.run_answer)
for t in tasks:
t.cancel()