8.13. Sterowanie pętlą#

Większość skryptów asyncio nigdy nie dotyka bezpośrednio pętli zdarzeń – asyncio.run() wystarcza. Ta strona omawia interfejs Loop dla przypadków, gdy to nie wystarcza: instalowania obsługi wyjątków, uruchamiania pętli z innym cyklem życia niż run lub przechowywania obiektu pętli na potrzeby instrumentacji.

8.13.1. Pobieranie pętli#

  • asyncio.get_event_loop() – zwraca obiekt Loop. Można go bezpiecznie wywołać zarówno wewnątrz, jak i na zewnątrz korutyny.

  • asyncio.new_event_loop() – w MicroPython resetuje stan istniejącej pętli, zamiast tworzyć nową. Warto powtórzyć uwagę: w programie istnieje dokładnie jedna pętla zdarzeń.

Nie ma API do uruchamiania pętli innego niż metody klasy Loop oraz asyncio.run().

8.13.2. Bezpośrednie uruchamianie pętli#

asyncio.run() to właściwy punkt wejścia dla niemal każdej aplikacji. Dla przypadków, gdy nim nie jest, istnieją dwie metody Loop.

  • run_until_complete() – mając dany obiekt awaitable, uruchamia pętlę do momentu jego zakończenia, a następnie zwraca jego wynik. Odpowiednik pojedynczego wywołania asyncio.run(), z pominięciem zburzenia pętli.

  • run_forever() – uruchamia pętlę, dopóki nie zostanie wywołane stop() z wnętrza zadania. Brak obiektu awaitable najwyższego poziomu; oczekuje się, że aplikacja zaplanuje to, czego potrzebuje, za pomocą asyncio.create_task() przed wywołaniem run_forever.

Metodami towarzyszącymi są stop() (żądanie zatrzymania pętli po zakończeniu bieżącego zadania) oraz close() (zwolnienie zasobów pętli).

8.13.3. Tworzenie zadań po stronie pętli#

  • create_task() – ta sama operacja co asyncio.create_task(). Wolna funkcja istnieje, aby kod aplikacji nie potrzebował referencji do pętli w typowym przypadku; metoda istnieje na potrzeby instrumentacji, która już ją posiada.

8.13.4. Obsługa wyjątków#

Pętla wywołuje funkcję obsługi, gdy zadanie zgłasza wyjątek, którego nic w łańcuchu wywołań korutyny nie przechwyciło – typowym przypadkiem jest zadanie utworzone przez aplikację za pomocą asyncio.create_task(), na które nigdy nie wykonano await. Domyślna funkcja obsługi wypisuje ślad stosu przez sys.stderr; strona o wyjątkach pokazała, jak podmienić ją na coś niestandardowego.

  • set_exception_handler() – instaluje niestandardową funkcję obsługi. Funkcja obsługi to obiekt wywoływalny handler(loop, context), gdzie context jest słownikiem zawierającym co najmniej 'message', a zazwyczaj również 'exception' i 'future'.

  • get_exception_handler() – zwraca aktualnie zainstalowaną funkcję obsługi lub None, jeśli używana jest domyślna.

  • default_exception_handler() – wbudowana funkcja obsługi. Przydatna wewnątrz niestandardowej funkcji obsługi, która chce również wykonać domyślne zachowanie (na przykład zapisać do pamięci flash oraz wypisać ślad stosu).

  • call_exception_handler() – uruchamia aktualnie zainstalowaną funkcję obsługi z ręcznie zbudowanym słownikiem kontekstu. Używane głównie przez samą pętlę; aplikacja rzadko tego potrzebuje.