Naše smyčka čekala 35 hodin sama na sebe: pgrep -f a pkill -f přes SSH

Provoz

31. října jsme spustili malou smyčku přes SSH: počkat, než na jiném stroji dokončí překladovou úlohu, a pak spustit navazující úlohu. Překladová úloha dokončila téhož večera. Když jsme se podívali znovu o dva dny později, smyčka čekala 35 hodin a navazující úloha se nikdy nespustila.

Co ta smyčka dělala

ssh build-host 'while pgrep -f "i18n_job.py example.com" >/dev/null; do sleep 30; done; ./follow-up.sh'

pgrep -f porovnává vzor s celým příkazovým řádkem každého procesu. SSH spustí uvozený příkaz jako bash -c 'while pgrep -f "i18n_job.py example.com" …' a tento příkazový řádek obsahuje vzor. pgrep vynechá svůj vlastní proces z výsledků, ale ne shell, který ho spustil. Takže dokud byla smyčka naživu, našla shodu: sama sebe.

Její dvojče: pkill -f zabije shell, ve kterém běží

Se pkill -f se děje totéž, s horšími následky:

ssh build-host 'pkill -f "worker.py --queue a"; nohup python3 worker.py --queue a &'

Příkazový řádek shellu obsahuje vzor, takže pkill zabije shell. Worker se zastaví a nikdy se znovu nespustí a SSH skončí s kódem 255 bez chybové hlášky. Vypadá to jako problém s uvozovkami, což jsme si zpočátku mysleli.

Mezi zářím a koncem října jsme do jednoho z nich nebo do druhého upadli nejméně tucetkrát: restarty, které se nikdy nestaly, smyčka, která držela kontrolu tři a půl hodiny, další, která držela frontu překladů 50 minut, a právě tato.

Co děláme teď

Factory Floor, balíček, který u nás pohání stroje, pracuje prostřednictvím systemd unit: nikdy nehledá proces podle příkazového řádku. Přesně ty smyčky, které nás zradily, jsme psali ručně.

Aktualizováno: