Resumo : neste tutorial, você aprenderá como usar a asyncio.wait_for()
função para aguardar a conclusão de uma corrotina com um tempo limite.
Introdução à função Python asyncio.wait_for()
No tutorial anterior, você aprendeu como cancelar uma tarefa que está em andamento usando o cancel()
método do Task
objeto.
Para aguardar a conclusão de uma tarefa com tempo limite, você pode usar a asyncio.wait_for()
função. A asyncio.wait_for()
função espera que uma única tarefa seja concluída com um tempo limite.
Quando ocorre um tempo limite, a asyncio.wait_for()
função cancela a tarefa e gera a TimeoutError
exceção. Caso contrário, retorna o resultado da tarefa. Por exemplo:
import asyncio
from asyncio.exceptions import TimeoutError
async def call_api(message, result=1000, delay=3):
print(message)
await asyncio.sleep(delay)
return result
async def main():
task = asyncio.create_task(
call_api('Calling API...', result=2000, delay=5)
)
MAX_TIMEOUT = 3
try:
await asyncio.wait_for(task, timeout=MAX_TIMEOUT)
except TimeoutError:
print('The task was cancelled due to a timeout')
asyncio.run(main())
Linguagem de código: JavaScript ( javascript )
Saída:
Calling API...
The task was cancelled due to a timeout
Como funciona
Primeiro, defina uma call_api()
corrotina que leva 3 segundos para ser concluída por padrão:
async def call_api(message, result=1000, delay=3):
print(message)
await asyncio.sleep(delay)
return result
Linguagem de código: JavaScript ( javascript )
Em segundo lugar, crie uma tarefa que envolva a corrotina call_api e leve 5 segundos para ser concluída:
task = asyncio.create_task(
call_api('Calling API...', result=2000, delay=5)
)
Linguagem de código: JavaScript ( javascript )
Terceiro, use a asyncio.wait_for()
função para aguardar a conclusão da tarefa com um tempo limite de 3 segundos. Como a tarefa leva 5 segundos para ser concluída, ocorrerá um tempo limite e um TimeoutError
será gerado:
MAX_TIMEOUT = 3
try:
await asyncio.wait_for(task, timeout=MAX_TIMEOUT)
except TimeoutError:
print('The task was cancelled due to a timeout')
Linguagem de código: PHP ( php )
Protegendo uma tarefa do cancelamento
Às vezes, você pode desejar informar aos usuários que uma tarefa está demorando mais do que o esperado após um determinado período de tempo, mas não cancelar a tarefa quando o tempo limite for excedido.
Para fazer isso, você pode agrupar a tarefa com a asyncio.shield()
função. Isso asyncio.shield()
evita o cancelamento de uma tarefa. Por exemplo:
import asyncio
from asyncio.exceptions import TimeoutError
async def call_api(message, result=1000, delay=3):
print(message)
await asyncio.sleep(delay)
return result
async def main():
task = asyncio.create_task(
call_api('Calling API...', result=2000, delay=5)
)
MAX_TIMEOUT = 3
try:
await asyncio.wait_for(asyncio.shield(task), timeout=MAX_TIMEOUT)
except TimeoutError:
print('The task took more than expected and will complete soon.')
result = await task
print(result)
asyncio.run(main())
Linguagem de código: JavaScript ( javascript )
Saída:
Calling API...
The task took more than expected and will complete soon.
2000
Neste exemplo, a tarefa leva 5 segundos para ser concluída. Quando o tempo limite for de 3 segundos, a TimeoutEror
exceção será gerada. Porém, a tarefa não é cancelada devido à asyncio.shield()
função.
Na seção de tratamento de exceções, await
concluímos a tarefa e imprimimos o resultado.
Resumo
- Use
asyncio.wait_for()
a função para aguardar uma tarefa com tempo limite. - Use
asyncio.shield()
a função para evitar o cancelamento de uma tarefa após um tempo limite.