Onze wachtlus wachtte 35 uur op zichzelf: pgrep -f en pkill -f via SSH

Ops

Op 31 oktober startten we een kleine lus via SSH: wacht tot een vertaaltaak op een andere machine klaar is, voer daarna een opvolgende taak uit. De vertaaltaak was die avond klaar. Toen we twee dagen later weer keken, had de lus 35 uur gewacht en was de opvolgende taak nooit uitgevoerd.

Wat de lus was

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

pgrep -f zoekt een patroon in de volledige commandoregel van elk proces. SSH voert de aangehaalde opdracht uit als bash -c 'while pgrep -f "i18n_job.py example.com" …', en die commandoregel bevat het patroon. pgrep laat zijn eigen proces buiten de resultaten, maar niet de shell die het heeft gestart. Zolang de lus leefde, vond hij dus een match: zichzelf.

Zijn tweeling: pkill -f beëindigt de shell waarin het draait

Hetzelfde gebeurt met pkill -f, met slechtere gevolgen:

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

De commandoregel van de shell bevat het patroon, dus pkill beëindigt de shell. De worker wordt gestopt en nooit meer gestart, en SSH sluit af met code 255 zonder foutmelding. Het lijkt op een probleem met aanhalingstekens, en daar hielden we het de eerste keer ook voor.

Tussen september en eind oktober liepen we minstens een dozijn keer in de ene of de andere val: herstarts die nooit plaatsvonden, een lus die een controle drieënhalf uur vasthield, een andere die een vertaalwachtrij 50 minuten vasthield, en deze.

Wat we nu doen

Factory Floor, de kit die onze machines aanstuurt, werkt via systemd-units: het zoekt nooit een proces op basis van de commandoregel. De lussen die ons parten speelden, waren die welke we met de hand hadden ingetypt.

Bijgewerkt: