Нашата циклична проверка изчака 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 units: той никога не търси процес по командния ред. Циклите, които ни подведоха, бяха тези, които въведохме ръчно.

Обновено: