Vår vänteslinga väntade i 35 timmar på sig själv: pgrep -f och pkill -f över SSH

Drift

Den 31 oktober startade vi en liten slinga över SSH: vänta tills ett översättningsjobb på en annan maskin är klart, kör sedan ett uppföljningsjobb. Översättningsjobbet blev klart samma natt. När vi tittade igen två dagar senare hade slingan väntat i 35 timmar, och uppföljningsjobbet hade aldrig körts.

Vad slingan var

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

pgrep -f matchar ett mönster mot hela kommandoraden för varje process. SSH kör det citerade kommandot som bash -c 'while pgrep -f "i18n_job.py example.com" …', och den kommandoraden innehåller mönstret. pgrep utesluter sin egen process från resultaten, men inte skalet som startade den. Så länge slingan levde hittade den alltså en matchning: sig själv.

Dess tvilling: pkill -f dödar skalet det körs i

Samma sak händer med pkill -f, med värre resultat:

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

Skalets egen kommandorad innehåller mönstret, så pkill dödar skalet. Workern stoppas och startas aldrig igen, och SSH avslutas med kod 255 utan felmeddelande. Det ser ut som ett citeringsproblem, vilket vi trodde första gången.

Mellan september och slutet av oktober råkade vi ut för det ena eller det andra minst ett dussin gånger: omstarter som aldrig hände, en slinga som höll en kontroll i tre och en halv timme, en annan som höll en översättningskö i 50 minuter, och den här.

Vad vi gör nu

Factory Floor, verktygspaketet som kör våra maskiner, fungerar via systemd-enheter: det söker aldrig efter en process via dess kommandorad. De loopar som bet oss i rumpan var de vi skrev för hand.

Uppdaterad: