Vòng chờ của chúng tôi đã chờ chính nó suốt 35 giờ: pgrep -f và pkill -f qua SSH

Vận hành

Vào ngày 31 tháng 10, chúng tôi khởi động một vòng lặp nhỏ qua SSH: chờ cho đến khi một công việc dịch thuật trên máy khác hoàn tất, rồi chạy một công việc tiếp theo. Công việc dịch thuật đã hoàn tất vào đêm đó. Khi chúng tôi kiểm tra lại hai ngày sau, vòng lặp đã chờ suốt 35 giờ, và công việc tiếp theo chưa bao giờ được chạy.

Vòng lặp đó là gì

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

pgrep -f so khớp một mẫu với toàn bộ dòng lệnh của mọi tiến trình. SSH chạy lệnh được bọc trong dấu nháy dưới dạng bash -c 'while pgrep -f "i18n_job.py example.com" …', và dòng lệnh đó chứa mẫu cần so khớp. pgrep loại trừ chính tiến trình của nó khỏi kết quả, nhưng không loại trừ shell đã khởi chạy nó. Vì vậy, chừng nào vòng lặp còn sống, nó sẽ tìm thấy một kết quả khớp: chính nó.

Anh em sinh đôi của nó: pkill -f giết chính shell mà nó đang chạy trong đó

Điều tương tự cũng xảy ra với pkill -f, nhưng với hậu quả tệ hơn:

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

Dòng lệnh của chính shell chứa mẫu cần so khớp, nên pkill giết shell đó. Worker bị dừng và không bao giờ được khởi động lại, còn SSH thoát với mã 255 mà không có thông báo lỗi. Nó trông giống như một vấn đề về dấu nháy, và đó là điều chúng tôi đã nghĩ lần đầu tiên.

Giữa tháng 9 và cuối tháng 10, chúng tôi đã rơi vào trường hợp này hoặc trường hợp kia ít nhất một tá lần: các lần khởi động lại không bao giờ xảy ra, một vòng lặp giữ một bước kiểm tra suốt ba tiếng rưỡi, một vòng lặp khác giữ hàng đợi dịch thuật suốt 50 phút, và trường hợp này.

Chúng tôi làm gì bây giờ

Factory Floor, bộ công cụ vận hành các máy của chúng tôi, hoạt động thông qua các unit systemd: nó không bao giờ tìm kiếm tiến trình dựa trên dòng lệnh. Những vòng lặp khiến chúng tôi gặp sự cố chính là những vòng lặp chúng tôi gõ thủ công.

Đã cập nhật: