Naša čakacia slučka čakala 35 hodín sama na seba: pgrep -f a pkill -f cez SSH

Prevádzka

31. októbra sme spustili malú slučku cez SSH: počkať, kým na inom počítači neskončí prekladová úloha, a potom spustiť nadväznú úlohu. Prekladová úloha skončila tej noci. Keď sme sa pozreli znova o dva dni neskôr, slučka čakala už 35 hodín a nadväzná úloha sa nikdy nespustila.

Čo slučka robila

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

pgrep -f porovnáva vzor s celým príkazovým riadkom každého procesu. SSH spustí zadaný príkaz ako bash -c 'while pgrep -f "i18n_job.py example.com" …' a tento príkazový riadok obsahuje vzor. pgrep vynechá svoj vlastný proces z výsledkov, ale nie shell, ktorý ho spustil. Takže pokiaľ bola slučka nažive, našla zhodu: seba samu.

Jej dvojča: pkill -f zabije shell, v ktorom beží

To isté sa stane s pkill -f, s horšími následkami:

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

Vlastný príkazový riadok shellu obsahuje vzor, takže pkill zabije shell. Pracovník sa zastaví a už sa nikdy nespustí a SSH ukončí prácu s kódom 255 bez chybovej správy. Vyzerá to ako problém s úvodzovkami, čo sme si zpočátku mysleli.

Medzi septembrom a koncom októbra sme aspoň tucetkrát narazili na jedno alebo druhé: reštarty, ktoré sa nikdy neudiali, slučka, ktorá držala kontrolu tri a pol hodiny, ďalšia, ktorá držala prekladový front 50 minút, a táto.

Čo robíme teraz

Factory Floor, balík, ktorý spúšťa naše stroje, funguje cez systemd unit: nikdy nehľadá proces podľa príkazového riadku. Slučky, ktoré nás dostali, boli tie, ktoré sme zadali ručne.

Aktualizované: