Nasza pętla czekała 35 godzin sama na siebie: pgrep -f i pkill -f przez SSH

Operacje

31 października uruchomiliśmy małą pętlę przez SSH: czekaj, aż zadanie tłumaczenia na innej maszynie się zakończy, a następnie uruchom zadanie następcze. Zadanie tłumaczenia zakończyło się tej samej nocy. Gdy zajrzeliśmy ponownie dwa dni później, pętla czekała już 35 godzin, a zadanie następcze nigdy się nie uruchomiło.

Czym była ta pętla

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

pgrep -f dopasowuje wzorzec do pełnej linii poleceń każdego procesu. SSH uruchamia cytowane polecenie jako bash -c 'while pgrep -f "i18n_job.py example.com" …', a ta linia poleceń zawiera ten wzorzec. pgrep pomija własny proces w wynikach, ale nie powłokę, która go uruchomiła. Zatem dopóki pętla żyła, znajdowała dopasowanie: samą siebie.

Jego bliźniak: pkill -f zabija powłokę, w której działa

To samo dzieje się z pkill -f, ze gorszymi skutkami:

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

Własna linia poleceń powłoki zawiera wzorzec, więc pkill zabija powłokę. Worker zostaje zatrzymany i nigdy nie zostaje uruchomiony ponownie, a SSH kończy działanie z kodem 255 bez komunikatu o błędzie. Wygląda to jak problem z cytowaniem, za co wzięliśmy to za pierwszym razem.

Od września do końca października wpadaliśmy w jedno lub drugie przynajmniej tuzin razy: restarty, które nigdy nie nastąpiły, pętla, która trzymała sprawdzenie przez trzy i pół godziny, inna, która trzymała kolejkę tłumaczeń przez 50 minut, i ta tutaj.

Co robimy teraz

Factory Floor, zestaw, który obsługuje nasze maszyny, działa w oparciu o jednostki systemd: nigdy nie szuka procesu po jego linii poleceń. Pętle, które nas dopadły, to te, które wpisaliśmy ręcznie.

Zaktualizowano: