Nuestro bucle de espera esperó 35 horas por sí mismo: pgrep -f y pkill -f sobre SSH

Operaciones

El 31 de octubre iniciamos un pequeño bucle sobre SSH: esperar hasta que un trabajo de traducción en otra máquina termine, y luego ejecutar un trabajo posterior. El trabajo de traducción terminó esa noche. Cuando volvimos a mirar dos días después, el bucle había estado esperando 35 horas y el trabajo posterior nunca se había ejecutado.

Qué era el bucle

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

pgrep -f hace coincidir un patrón con la línea de comandos completa de cada proceso. SSH ejecuta el comando entre comillas como bash -c 'while pgrep -f "i18n_job.py example.com" …', y esa línea de comandos contiene el patrón. pgrep excluye su propio proceso de los resultados, pero no el shell que lo inició. Así que, mientras el bucle estaba vivo, encontraba una coincidencia: él mismo.

Su gemelo: pkill -f mata al shell en el que se ejecuta

Lo mismo ocurre con pkill -f, con peores resultados:

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

La línea de comandos del propio shell contiene el patrón, por lo que pkill mata al shell. El worker se detiene y nunca se vuelve a iniciar, y SSH sale con el código 255 sin un mensaje de error. Parece un problema de comillas, que es lo que pensamos la primera vez.

Entre septiembre y finales de octubre caímos en uno u otro al menos una docena de veces: reinicios que nunca ocurrieron, un bucle que mantuvo una comprobación durante tres horas y media, otro que mantuvo una cola de traducción durante 50 minutos, y este.

Qué hacemos ahora

Factory Floor, el kit que ejecuta nuestras máquinas, funciona mediante unidades de systemd: nunca busca un proceso por su línea de comandos. Los bucles que nos dieron problemas fueron los que escribimos a mano.

Actualizado: