E / S assíncronas paralelas nas corotinas do Python
Exemplo simples: preciso fazer duas solicitações HTTP não relacionadas em paralelo. Qual é a maneira mais simples de fazer isso? Eu espero que seja assim:
async def do_the_job():
with aiohttp.ClientSession() as session:
coro_1 = session.get('http://httpbin.org/get')
coro_2 = session.get('http://httpbin.org/ip')
return combine_responses(await coro_1, await coro_2)
Em outras palavras, desejo iniciar operações de E / S e aguardar seus resultados para que eles efetivamente sejam executados em paralelo. Isso pode ser alcançado comasyncio.gather
:
async def do_the_job():
with aiohttp.ClientSession() as session:
coro_1 = session.get('http://example.com/get')
coro_2 = session.get('http://example.org/tp')
return combine_responses(*(await asyncio.gather(coro_1, coro_2)))
Em seguida, quero ter uma estrutura de dependência complexa. Quero iniciar as operações quando tiver todos os pré-requisitos para elas e obter resultados quando precisar. Aqui ajudaasyncio.ensure_future
que cria uma tarefa separada da rotina que é gerenciada pelo loop de eventos separadamente:
async def do_the_job():
with aiohttp.ClientSession() as session:
fut_1 = asyncio.ensure_future(session.get('http://httpbin.org/ip'))
coro_2 = session.get('http://httpbin.org/get')
coro_3 = session.post('http://httpbin.org/post', data=(await coro_2)
coro_3_result = await coro_3
return combine_responses(await fut_1, coro_3_result)
É verdade que, para obter E / S paralelas sem bloqueio com corotinas no meu fluxo lógico, eu tenho que usarasyncio.ensure_future
ouasyncio.gather
(que realmente usaasyncio.ensure_future
)? Existe uma maneira menos "detalhada"?
É verdade que normalmente os desenvolvedores precisam pensar em quais corotinas devem se tornar tarefas separadas e usar as funções mencionadas para obter o desempenho ideal?
Existe um ponto em usar corotinas sem várias tarefas no loop de eventos?
Quão "pesadas" são as tarefas de loop de eventos na vida real? Certamente, eles são "mais leves" do que processos ou threads do SO. Até que ponto devo me esforçar para obter o número mínimo possível dessas tarefas?