8.13. Controlo do loop

A maioria dos scripts asyncio nunca toca diretamente no event loop – asyncio.run() é suficiente. Esta página cobre a interface Loop para os casos em que não é: instalar um gestor de exceções, executar o loop com um ciclo de vida diferente do de run, ou manter o objeto loop para instrumentação.

8.13.1. Obter o loop

  • asyncio.get_event_loop() – devolve o objeto Loop. Seguro para chamar dentro ou fora de uma coroutine.

  • asyncio.new_event_loop() – no MicroPython, reinicia o estado do loop existente em vez de criar um novo. Vale a pena repetir a nota: existe exatamente um event loop por programa.

Não existe API para executar o loop para além dos métodos em Loop e asyncio.run().

8.13.2. Executar o loop diretamente

asyncio.run() é o ponto de entrada correto para quase todas as aplicações. Existem dois métodos de Loop para os casos em que não é.

  • run_until_complete() – dado um aguardável, executa o loop até que esse aguardável termine, depois devolve o seu resultado. Equivalente a uma única chamada a asyncio.run(), sem a fase de desmontagem do loop.

  • run_forever() – executa o loop até que stop() seja chamado a partir de dentro de uma tarefa. Sem aguardável de nível superior; a aplicação deverá escalonar o que precisar através de asyncio.create_task() antes de chamar run_forever.

Os métodos complementares são stop() (solicitar ao loop que pare após a tarefa atual terminar) e close() (libertar os recursos do loop).

8.13.3. Criação de tarefas no lado do loop

  • create_task() – mesma operação que asyncio.create_task(). A função livre existe para que o código da aplicação não precise de uma referência ao loop no caso comum; o método existe para instrumentação que já dispõe de uma.

8.13.4. Gestores de exceções

O loop chama um gestor quando uma tarefa lança uma exceção que nada na cadeia de chamadas da coroutine capturou – um caso típico sendo uma tarefa que a aplicação criou com asyncio.create_task() e nunca aguardou. O gestor predefinido imprime um traceback através de sys.stderr; a página de exceções mostrou como substituí-lo por algo personalizado.

  • set_exception_handler() – instala um gestor personalizado. O gestor é um callable handler(loop, context) onde context é um dict com pelo menos 'message' e normalmente 'exception' e 'future'.

  • get_exception_handler() – devolve o gestor atualmente instalado, ou None se o predefinido estiver em uso.

  • default_exception_handler() – o gestor incorporado. Útil dentro de um gestor personalizado que também quer executar o comportamento predefinido (registar em flash e imprimir um traceback, por exemplo).

  • call_exception_handler() – executa o gestor atualmente instalado com um dict de contexto construído manualmente. Usado principalmente pelo próprio loop; uma aplicação raramente precisa disto.