Naš petlja za čekanje čekala je 35 sati sama na sebe: pgrep -f i pkill -f preko SSH-a
Operacije
31. oktobra pokrenuli smo malu petlju preko SSH-a: čekaj da se završi posao prevođenja na drugoj mašini, pa pokreni nadogradnju. Posao prevođenja završio je te noći. Kada smo ponovo pogledali dva dana kasnije, petlja je čekala 35 sati, a nadogradnja nikada nije pokrenuta.
Šta je petlja bila
ssh build-host 'while pgrep -f "i18n_job.py example.com" >/dev/null; do sleep 30; done; ./follow-up.sh'
pgrep -f uparuje obrazac sa punom komandnom linijom svakog procesa. SSH pokreće navedenu komandu kao bash -c 'while pgrep -f "i18n_job.py example.com" …', a ta komandna linija sadrži obrazac. pgrep izbacuje sopstveni proces iz rezultata, ali ne i shell koji ga je pokrenuo. Dakle, dokle god je petlja bila živa, nalazila je podudaranje: samu sebe.
Njen blizanac: pkill -f ubija shell u kojem se izvršava
Isto se dešava sa pkill -f, sa lošijim posledicama:
ssh build-host 'pkill -f "worker.py --queue a"; nohup python3 worker.py --queue a &'
Komandna linija shella sadrži obrazac, pa pkill ubija shell. Radnik je zaustavljen i nikada ponovo pokrenut, a SSH izlazi sa kodom 255 bez poruke o grešci. Izgleda kao problem sa navodnicima, što smo i pomislili prvi put.
Između septembra i kraja oktobra upali smo u jedno ili drugo bar desetak puta: restarti koji se nikada nisu desili, petlja koja je držala proveru tri i po sata, druga koja je držala red za prevođenje 50 minuta, i ova.
Šta sada radimo
- Zagrada u obrascu:
pgrep -f "[i]18n_job.py example.com". Kao regularni izraz,[i]uparuje slovo i, pa posao i dalje odgovara; komandna linija shella sadrži karaktere[i], koje izraz ne uparuje. Ovo pomaže samo ako se običan obrazac ne pojavljuje nigde drugde na toj liniji: komanda za restart kasnije na istoj liniji ponovo odgovara. - Pronađi, zaustavi i pokreni u odvojenim SSH pozivima. Jedan poziv nabraja procese sa
pgrep -af, sledeći ubija PID-ove koje je ispisao, treći pokreće novi proces. - Čekaj na PID, ne na obrazac:
tail --pid=1234 -f /dev/null, iliwhile kill -0 1234; do sleep 30; done. - Još bolje, prepustite posao systemd-u. Pokrenite ga kao jedinicu i proverite sa
systemctl is-active, ili ga pokrenite sasystemd-run --wait. Ne postoji obrazac koji biste mogli pogrešno da primenite. - Svako čekanje ima rok (
timeout 3h) i navodi kada odustaje. Petlja bez roka neuspešno završava bez najave.
Factory Floor, komplet koji pokreće naše mašine, radi putem systemd jedinica: nikada ne traži proces po komandnoj liniji. Petlje koje su nas izneverile bile su one koje smo kucali ručno.