Zámek, který nečeká

Dvakrát za hodinu na dost velkém webu sáhnou dvě úlohy cronu do téže složky téměř ve stejnou chvíli: naplánované publikování, které sestaví a nasadí příspěvek, jehož čas právě nastal, a obnova postranního panelu, která přepisuje několik týchž výstupních souborů čerstvými čísly. Většina tiků se mine o minuty. Na archivu tak velkém, že sestavení s úplným nasazením trvá déle než interval mezi nimi, se některé neminou.

Nasazení, které prochází strom, zatímco ho jiný běh ještě přepisuje, může vydat stránku zapsanou napůl. Běh, který maže osiřelé soubory, může jako osiřelou smazat stránku, kterou druhý běh o sekundu dřív publikoval. Ani jedno selhání se neohlásí – web je prostě potichu špatně.

Zámek a co odmítá dělat

Mezi těmi dvěma běhy stojí jediný soubor, .blog-sh.lock v kořeni projektu – a rozhoduje se způsobem, který vypadá špatně, dokud neuvidíš alternativu. Běh, který najde zámek obsazený, na něj nečeká.

Tik cronu, který ten závod prohraje, to ohlásí a odejde s kódem 0. Cron nepotřebuje, aby čekal: další tik přijde za pár minut tak jako tak a alternativa – stát ve frontě za zámkem – má horší podobu selhání než ztráta jednoho kola. Hromada zablokovaných běhů se probudí naráz ve chvíli, kdy se zámek uvolní, a všechny se pustí do téže práce zároveň.

Běh spuštěný ručně má jiný slib. Kolizi ohlásí a skončí nenulovým kódem, protože tichá alternativa – uspět v ničem a přitom vypadat jako úspěch – by znamenala, že ti ./blog.sh tvrdí, že nasazení proběhlo, když neproběhlo.

Jedna operace, ne tři

Publikování podle plánu znamená publikovat, sestavit a nasadit těsně za sebou a zámek se drží po celou dobu naráz, místo aby se mezi kroky získával znovu – sestavení spuštěné ve chvíli, kdy publikace skončí, je přesně ten překryv, kterému má zámek bránit, jen s ním samým na obou stranách. Sestavení a nasazení, která publikace spouští, tentýž zámek dědí místo toho, aby žádala o vlastní; to je rozdíl mezi během, který drží dveře otevřené těm svým částem, které přijdou po něm, a během, který se zablokuje proti vlastnímu potomkovi.

Kde volba vůbec nevzniká

Přeskládání fronty bere tentýž zámek, a je to jediné místo, kde se výše popsaný vzor láme – stojí za to to pojmenovat, ne přejít. Nedotýká se public.nosync; zapisuje do týchž souborů příspěvků, ze kterých by naplánované publikování četlo, a zámek drží jen po dobu samotného přesunu, kontroly a zápisy dohromady a nic déle, nikdy ne ve chvíli, kdy je otevřený dialog a čeká, až vybereš slot. Volba cron versus člověk tu nevzniká, protože není co ztratit: operace, která skončí dřív, než by vůbec mohl dorazit další tik, nemusí volit mezi čekáním a odchodem. Obrazovka fronty otevřená přes noc ještě nikdy nezadržela tik cronu – ne proto, že by byla postavená jako ohleduplná, ale proto, že nikdy nebyla otevřená dost dlouho, aby stála v cestě.

Kde souborový systém poradní zámky (advisory locks) neumí vůbec – některá síťová připojení – degraduje zámek potichu na žádný zámek, což je přesně stav, ve kterém stála každá instalace, než tento zámek existoval.

Komentáře