SoftvérZdroj: Hacker News

Prečo asyncio v Pythone zápasí so zdieľaným stavom a čo s tým robiť

Asyncio v Pythone pravidelne zápasí s koordináciou asynchrónnych úloh okolo zdieľaného stavu. Najčastejšie používané prvky asyncio.Event a asyncio.Condition majú medzery, ktoré vedú k strate aktualizácií. V článku preskúmame tieto problémy a prezentujeme riešenie využívajúce záznamové fronty na elimináciu chýb.

Řešení problémů s asyncio v Pythonu a novinky od Nothing Phone

Problematika zdieľaného stavu v asyncio

V rámci populárneho jazyka Python a jeho knižnice asyncio sa pravidelne stretávame s potrebou koordinácie asynchrónnych úloh v súvislosti so zdieľaným stavom. Hoci štandardná knižnica ponúka nástroje ako asyncio.Event a asyncio.Condition, oba majú svoje nedostatky, ktoré naplno vyvstávajú pri skutočnom tlaku konkurenčných úloh.

Pokusy o riešenie

Prvá myšlienka je použitie pole, teda cyklického kontrolovania aktuálneho stavu. Tento prístup však trpí buď zbytočným zaťažením CPU alebo zbytočnou latenciou. Nasledujúce pokusy zahŕňajú asyncio.Event, ktorý síce eliminuje pole, ale neprakticky proliferuje viaceré udalosti pre rôzne stavy, čo vedie k možným chybám v koordinácii.

Problém 'stratenej' aktualizácie

Najvýznamnejší problém s asyncio.Condition je tzv. 'stratená' aktualizácia, kde rýchlo nasledujúce zmeny stavu môžu prebehnúť skôr, než sa spotrebiteľské úlohy zobudia, reakčne zareagujú a vedome skontrolujú aktuálny stav. To môže viesť k úplnému vynechaniu niektorých premien stavu spotrebiteľskými úlohami.

Riešenie s využitím záznamových front

Jednoúčelové riešenie pre tento problém ponúka vytvorenie záznamových front pre každý spotrebiteľ. Pri zmene stavu sa pre každého spotrebiteľa zaznamená stará a nová hodnota do jeho fronty a spotrebiteľ samostatne vyhodnocuje každý zápis vo fronte.

Ako to nasadiť

Pre finálnu implementáciu je potrebné pridať niekoľko ďalších prvkov, ako sú ochrana pred súbežnými závitmi pomocou threading.Lock, atomická registrácia front a zohľadnenie výpadkov s použitím výnimiek.

Vylepšenie kódu pre produkčné prostredie

Pre použitie v produkčnom prostredí je nevyhnutné pridanie generického typovania, časových obmedzení a metód pre sledovanie zmien, vrátane synchronných sledovacích callbackov. Kompletná implementácia obsahuje približne 300 riadkov kódu, pričom väčšinu tvoria komentáre a užívateľské metódy.