Ο βρόχος αναμονής μας περίμενε τον εαυτό του για 35 ώρες: pgrep -f και pkill -f μέσω SSH

Λειτουργίες

Στις 31 Οκτωβρίου ξεκινήσαμε έναν μικρό βρόχο μέσω SSH: περίμενε να ολοκληρωθεί μια εργασία μετάφρασης σε άλλη μηχανή και στη συνέχεια να εκτελέσει μια παρακολούθηση. Η εργασία μετάφρασης ολοκληρώθηκε εκείνο το βράδυ. Όταν ξανακοιτάξαμε δύο ημέρες αργότερα, ο βρόχος περίμενε για 35 ώρες και η παρακολούθηση δεν είχε εκτελεστεί ποτέ.

Τι ήταν ο βρόχος

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

Το pgrep -f ταιριάζει με ένα μοτίβο σε σχέση με τη πλήρη γραμμή εντολών κάθε διεργασίας. Το SSH εκτελεί την εντολή με εισαγωγικά ως bash -c 'while pgrep -f "i18n_job.py example.com" …', και αυτή η γραμμή εντολών περιέχει το μοτίβο. Το pgrep εξαιρεί τη δική του διεργασία από τα αποτελέσματα, αλλά όχι το κέλυφος που την ξεκίνησε. Έτσι, όσο ο βρόχος ήταν ζωντανός, έβρισκε μια αντιστοιχία: τον εαυτό του.

Ο δίδυμος του: το pkill -f σκοτώνει το κέλυφος στο οποίο εκτελείται

Το ίδιο συμβαίνει με το pkill -f, με χειρότερα αποτελέσματα:

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

Η δική του γραμμή εντολών του κελύφους περιέχει το μοτίβο, οπότε το pkill σκοτώνει το κέλυφος. Ο εργαζόμενος σταματά και δεν ξεκινά ξανά, και το SSH τερματίζεται με κωδικό 255 χωρίς μήνυμα σφάλματος. Μοιάζει με πρόβλημα εισαγωγικών, κάτι που το θεωρήσαμε την πρώτη φορά.

Από τον Σεπτέμβριο έως το τέλος Οκτωβρίου πέσαμε στον έναν ή τον άλλο τουλάχιστον μια δεκαπενταριά φορές: επανεκκινήσεις που δεν έγιναν ποτέ, ένας βρόχος που κράτησε έναν έλεγχο για τρεισήμισι ώρες, ένας άλλος που κράτησε μια ουρά μεταφράσεων για 50 λεπτά, και αυτός εδώ.

Τι κάνουμε τώρα

Factory Floor, η εργαλειοθήκη που τρέχει τις μηχανές μας, λειτουργεί μέσω μονάδων systemd: δεν ψάχνει ποτέ μια διαδικασία από τη γραμμή εντολών της. Οι βρόχοι που μας έκαψαν ήταν αυτοί που πληκτρολογήσαμε με το χέρι.

Ενημερώθηκε: