Параллельное выполнение запросов
У меня есть 2 асинхронных запроса. Я хочу, чтобы они выполнялись в параллель друг другу. Поясню.Я хочу, чтобы к моменту, когда я сделаю await resp_a, и fetch(a), и fetch(b) уже скорее всего отработали и мне не потребуется ожидать ответа от сервера?
resp_a = fetch(a)
resp_b = fetch(b)
time.sleep(long_time)
await resp_a
await resp_b
В реальности, после выполнения fetch(a), запроса к серверу не происходит. Происходит он лишь в момент времени await resp_a. По крайней мере, так происходит в дебаггере.
Есть 2 запроса к разным сервисам. Считаем, что они достаточно тяжёлые. Хочется, не дожидаться их ответа, а выполнять их в параллель.
async def fetch():
print('2')
...
print('1')
resp_a = fetch(a) # Тяжёлый запрос 1
print('3')
resp_b = fetch(b) # Тяжёлый запрос 2
time.sleep(long_time) # Тяжёлая обработка. Где-то здесь, в параллель с этой тяжёлой обработкой запрос 1 обработался и запрос 2 обработался.
await resp_a
await resp_b
Как я говорил выше, если выполнять в дебаггере, я получу:
1 2 3
Без
1 3 2
Ответы (1 шт):
resp_a = fetch(a)
resp_b = fetch(b)
Не выполняет запросов, а только создает структуру асинхронных вызовов. awaitable объект.
Начать его выполнять его надо присоединить к loop. Слово await делает из awaitable future b выполняет все запланированные future.
Чтоб выполнить их параллельно следует использовать asyncio.gather или asyncio.wait, иногда случае enshure_future
gather - выполняет оба запроса конкурентно
result_a, result_b = await asyncio.gather(resp_a,resp_b) # выполняет запросы
wait - запускает оба запроса, возвращает первый или все
done, pending = await asyncio.wait([resp_a,resp_b],return_when=FIRST_COMPLETED)
first = await done
done, pending = await asyncio.wait(pending,return_when=FIRST_COMPLETED)
second = await done
asyncio.ensure_future - запускает запрос
resp_a = asyncio.ensure_future(fetch(a))
resp_b = asyncio.ensure_future(fetch(b))
Запрос запущен, но ещё не отправлен.
time.sleep(long_time)
всё ещё не запущен, time.sleep блокирует выполнение запросов
await asyncio.sleep(long_time)
вот тут запустятся все три: resp_b,resp_a, sleep и ждем sleep
await resp_a
await resp_b
Дожидаемся resp_a, а потом resp_b.