Loop tunggu kami menunggu dirinya sendiri selama 35 jam: pgrep -f dan pkill -f melalui SSH
Ops
Pada 31 Oktober, kami memulai loop kecil melalui SSH: tunggu hingga pekerjaan terjemahan di mesin lain selesai, lalu jalankan pekerjaan lanjutan. Pekerjaan terjemahan selesai malam itu. Ketika kami memeriksanya lagi dua hari kemudian, loop tersebut telah menunggu selama 35 jam, dan pekerjaan lanjutan tidak pernah berjalan.
Apa yang dilakukan loop tersebut
ssh build-host 'while pgrep -f "i18n_job.py example.com" >/dev/null; do sleep 30; done; ./follow-up.sh'
pgrep -f mencocokkan pola dengan baris perintah lengkap dari setiap proses. SSH menjalankan perintah yang dikutip sebagai bash -c 'while pgrep -f "i18n_job.py example.com" …', dan baris perintah tersebut mengandung pola tersebut. pgrep mengecualikan prosesnya sendiri dari hasil, tetapi tidak shell yang memulainya. Jadi selama loop masih hidup, ia menemukan kecocokan: dirinya sendiri.
Padanannya: pkill -f membunuh shell tempat ia berjalan
Hal yang sama terjadi dengan pkill -f, dengan hasil yang lebih buruk:
ssh build-host 'pkill -f "worker.py --queue a"; nohup python3 worker.py --queue a &'
Baris perintah shell itu sendiri mengandung pola tersebut, sehingga pkill membunuh shell tersebut. Worker dihentikan dan tidak pernah dimulai lagi, dan SSH keluar dengan kode 255 tanpa pesan kesalahan. Tampak seperti masalah pengutipan, yang kami kira pada awalnya.
Antara September hingga akhir Oktober, kami terjebak pada salah satu dari keduanya setidaknya selusin kali: restart yang tidak pernah terjadi, loop yang menahan pemeriksaan selama tiga setengah jam, loop lain yang menahan antrean terjemahan selama 50 menit, dan yang satu ini.
Apa yang kami lakukan sekarang
- Gunakan kurung siku dalam pola:
pgrep -f "[i]18n_job.py example.com". Sebagai ekspresi reguler,[i]cocok dengan huruf i, sehingga pekerjaan tetap cocok; baris perintah shell mengandung karakter[i], yang tidak cocok dengan ekspresi tersebut. Ini hanya membantu jika pola polos tidak muncul di tempat lain pada baris yang sama: perintah restart di bagian akhir baris yang sama akan kembali cocok. - Temukan, hentikan, dan mulai dalam panggilan SSH terpisah. Satu panggilan mencantumkan proses dengan
pgrep -af, panggilan berikutnya membunuh PID yang dicetak, dan panggilan ketiga memulai proses baru. - Tunggu pada PID, bukan pola:
tail --pid=1234 -f /dev/null, atauwhile kill -0 1234; do sleep 30; done. - Lebih baik lagi, biarkan systemd yang menangani pekerjaan tersebut. Jalankan sebagai unit dan tanyakan
systemctl is-active, atau mulai dengansystemd-run --wait. Tidak ada pola yang salah. - Setiap penantian memiliki batas waktu (
timeout 3h) dan menyatakan kapan menyerah. Loop tanpa batas waktu gagal secara diam-diam.
Factory Floor, Paket Kit yang menjalankan mesin kami, bekerja melalui unit systemd: tidak pernah mencari proses berdasarkan baris perintahnya. Loop yang membuat kami kesulitan adalah yang kami ketik secara manual.