Il nostro loop di attesa ha atteso 35 ore per se stesso: pgrep -f e pkill -f via SSH

Ops

Il 31 ottobre abbiamo avviato un piccolo loop via SSH: attendere il completamento di un lavoro di traduzione su un'altra macchina, quindi eseguire un lavoro successivo. Il lavoro di traduzione è terminato quella notte. Quando abbiamo ricontrollato due giorni dopo, il loop era in attesa da 35 ore e il lavoro successivo non era mai stato eseguito.

Cos'era il loop

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

pgrep -f confronta un pattern con la riga di comando completa di ogni processo. SSH esegue il comando tra virgolette come bash -c 'while pgrep -f "i18n_job.py example.com" …', e quella riga di comando contiene il pattern. pgrep esclude il proprio processo dai risultati, ma non la shell che lo ha avviato. Quindi, finché il loop era attivo, trovava una corrispondenza: se stesso.

Il suo gemello: pkill -f uccide la shell in cui viene eseguito

La stessa cosa accade con pkill -f, con risultati peggiori:

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

La riga di comando della shell stessa contiene il pattern, quindi pkill uccide la shell. Il worker viene fermato e non viene mai riavviato, e SSH esce con il codice 255 senza messaggi di errore. Sembra un problema di virgolettatura, che è ciò che abbiamo pensato la prima volta.

Tra settembre e la fine di ottobre siamo incappati nell'uno o nell'altro almeno una dozzina di volte: riavvii mai avvenuti, un loop che ha trattenuto un controllo per tre ore e mezza, un altro che ha trattenuto una coda di traduzioni per 50 minuti, e questo.

Cosa facciamo ora

Factory Floor, il kit che gestisce le nostre macchine, funziona tramite unit systemd: non cerca mai un processo dalla riga di comando. I loop che ci hanno creato problemi erano quelli che avevamo scritto a mano.

Aggiornato: