8.13. Controle do loop

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

8.13.1. Obtendo o loop

  • asyncio.get_event_loop() – retorna o objeto Loop. Pode ser chamado com segurança de dentro ou de fora de uma corrotina.

  • asyncio.new_event_loop() – no MicroPython, reinicia o estado do loop existente em vez de criar um novo. A observação merece ser repetida: há exatamente um event loop por programa.

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

8.13.2. Executando o loop diretamente

asyncio.run() é o ponto de entrada correto para quase toda aplicação. Dois métodos de Loop existem para os casos em que ele não é.

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

  • run_forever() – executa o loop até que stop() seja chamado de dentro de uma tarefa. Não há aguardável de nível superior; espera-se que a aplicação agende o que precisar via asyncio.create_task() antes de chamar run_forever.

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

8.13.3. Criação de tarefas pelo 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 a instrumentação que já possui uma.

8.13.4. Manipuladores de exceções

O loop chama um manipulador quando uma tarefa levanta uma exceção que nada na cadeia de chamadas da corrotina capturou – um caso típico sendo uma tarefa que a aplicação criou com asyncio.create_task() e nunca aguardou. O manipulador padrão 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 manipulador personalizado. O manipulador é um chamável handler(loop, context) em que context é um dicionário com ao menos 'message' e, geralmente, 'exception' e 'future'.

  • get_exception_handler() – retorna o manipulador atualmente instalado, ou None se o padrão estiver em uso.

  • default_exception_handler() – o manipulador embutido. Útil dentro de um manipulador personalizado que deseja também executar o comportamento padrão (registrar na flash e imprimir um traceback, por exemplo).

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