Notre boucle d'attente a attendu 35 heures pour elle-même : pgrep -f et pkill -f via SSH

Opérations

Le 31 octobre, nous avons lancé une petite boucle via SSH : attendre la fin d'un job de traduction sur une autre machine, puis exécuter un job de suivi. Le job de traduction s'est terminé cette nuit-là. Quand nous avons regardé à nouveau deux jours plus tard, la boucle attendait depuis 35 heures, et le job de suivi n'avait jamais été exécuté.

Ce qu'était la boucle

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

pgrep -f compare un motif à la ligne de commande complète de chaque processus. SSH exécute la commande entre guillemets comme bash -c 'while pgrep -f "i18n_job.py example.com" …', et cette ligne de commande contient le motif. pgrep exclut son propre processus des résultats, mais pas le shell qui l'a lancé. Ainsi, tant que la boucle était active, elle trouvait une correspondance : elle-même.

Son jumeau : pkill -f tue le shell dans lequel il s'exécute

La même chose se produit avec pkill -f, avec des résultats pires :

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

La ligne de commande du shell contient le motif, donc pkill tue le shell. Le worker est arrêté et n'est jamais relancé, et SSH se termine avec le code 255 sans message d'erreur. Cela ressemble à un problème de guillemets, ce que nous avons cru la première fois.

Entre septembre et fin octobre, nous sommes tombés dans l'un ou l'autre au moins une douzaine de fois : des redémarrages qui n'ont jamais eu lieu, une boucle qui a bloqué une vérification pendant trois heures et demie, une autre qui a bloqué une file de traduction pendant 50 minutes, et celle-ci.

Ce que nous faisons maintenant

Factory Floor, le Kit qui pilote nos machines, fonctionne via des unités systemd : il ne cherche jamais un processus par sa ligne de commande. Les boucles qui nous ont posé problème étaient celles que nous avions saisies à la main.

Mis à jour: