Python assíncio.wait_for()

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 Taskobjeto.

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 TimeoutErrorexceçã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 resultLinguagem 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 TimeoutErrorserá 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 TimeoutErorexceção será gerada. Porém, a tarefa não é cancelada devido à asyncio.shield()função.

Na seção de tratamento de exceções, awaitconcluí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.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *