8.3. Smyčka událostí

Smyčka událostí je engine, který asyncio běží pod tím vším. Udržuje seznam každé úlohy v programu, požádá každou z nich, aby běžela až do svého nejbližšího await, a přejde na další připravenou úlohu. Když nejsou žádné připravené úlohy, čeká — toto skutečné čekání je to, co uvolňuje procesor, aby firmware mohl běžet jiné věci a aby se mohla uplatnit úsporná uspání — dokud nebude dostupné něco, na co úloha čekala, a poté tuto úlohu obnoví. A tak stále dokola.

Většina aplikací se smyčkou nikdy přímo neinteraguje. Smyčka je důsledkem volání asyncio.run(); aplikace píše korutiny, plánuje je jako úlohy a smyčka udělá zbytek.

8.3.1. Co asyncio.run() ve skutečnosti dělá

Jediné volání:

asyncio.run(main())

je zkratkou za delší sekvenci, kterou smyčka spravuje jménem aplikace:

  1. Vytvoří smyčku událostí, pokud ještě neexistuje.

  2. Zabalí dodanou korutinu do úlohy a naplánuje ji jako vrcholový vstupní bod smyčky.

  3. Spustí smyčku — postupně prochází připravené úlohy, čeká, když žádná není připravena, obnovuje úlohy, když se jejich awaity dokončí — dokud se vrcholová úloha nevrátí nebo nevyvolá výjimku.

  4. Zruší veškeré úlohy, které aplikace vytvořila a které stále běží.

  5. Vrátí to, co vrátila vrcholová korutina (nebo znovu vyvolá to, co vyvolala).

8.3.2. Jedna smyčka na program

Asyncio v MicroPythonu má jednu smyčku událostí, tečka. Neexistuje vytváření nové smyčky a neexistuje vnořování jedné smyčky do druhé. Volání asyncio.run() zevnitř korutiny, která již běží na smyčce, je chybou; smyčka už tam je a korutina prostě potřebuje awaitovat to, co chtěla spustit.

V praxi je pravidlo stejné jako závěrečný řádek předchozí stránky: na program připadá přesně jedno volání asyncio.run(), na vrcholu, za nímž je jediná async def main(). Vše ostatní žije uvnitř main.

8.3.3. Přímý přístup ke smyčce

Pro vzácné případy, kdy aplikace potřebuje sáhnout na smyčku samotnou — většinou diagnostika a obslužné rutiny výjimek — vrací asyncio.get_event_loop() objekt Loop. Odtud může aplikace nainstalovat vlastní obslužnou rutinu výjimek, zkoumat, co smyčka dělá, nebo (velmi výjimečně) volat create_task() přímo namísto asyncio.create_task() (jde o stejnou operaci).

Kompletní sadu metod, které Loop poskytuje — run_forever(), stop(), set_exception_handler() a zbytek — popisuje stránka o řízení smyčky později v této sekci. Do té doby je asyncio.run(main()) vše, co aplikace potřebuje.