Gelung tunggu kami menunggu dirinya sendiri selama 35 jam: pgrep -f dan pkill -f melalui SSH
Operasi
Pada 31 Oktober, kami memulakan gelung kecil melalui SSH: tunggu sehingga kerja terjemahan pada mesin lain selesai, kemudian jalankan kerja susulan. Kerja terjemahan itu selesai pada malam tersebut. Apabila kami melihat semula dua hari kemudian, gelung itu telah menunggu selama 35 jam, dan kerja susulan tidak pernah dijalankan.
Apa yang gelung itu lakukan
ssh build-host 'while pgrep -f "i18n_job.py example.com" >/dev/null; do sleep 30; done; ./follow-up.sh'
pgrep -f memadankan corak dengan baris arahan penuh bagi setiap proses. SSH menjalankan arahan yang dipetik sebagai bash -c 'while pgrep -f "i18n_job.py example.com" …', dan baris arahan itu mengandungi corak tersebut. pgrep mengecualikan prosesnya sendiri daripada hasil, tetapi bukan shell yang memulakannya. Jadi, selagi gelung itu hidup, ia menemui padanan: dirinya sendiri.
Kembarannya: pkill -f membunuh shell tempat ia dijalankan
Perkara yang sama berlaku dengan pkill -f, dengan kesan yang lebih buruk:
ssh build-host 'pkill -f "worker.py --queue a"; nohup python3 worker.py --queue a &'
Baris arahan shell itu sendiri mengandungi corak tersebut, jadi pkill membunuh shell itu. Pekerja dihentikan dan tidak dimulakan semula, dan SSH keluar dengan kod 255 tanpa mesej ralat. Ia kelihatan seperti masalah petikan, yang kami sangka pada mulanya.
Antara September hingga akhir Oktober, kami terjebak dalam salah satu daripada situasi ini sekurang-kurangnya selusin kali: permulaan semula yang tidak pernah berlaku, gelung yang menahan pemeriksaan selama tiga setengah jam, satu lagi yang menahan baris gilir terjemahan selama 50 minit, dan yang ini.
Apa yang kami lakukan sekarang
- Letak kurungan dalam corak:
pgrep -f "[i]18n_job.py example.com". Sebagai ungkapan biasa,[i]memadankan huruf i, jadi kerja itu masih dipadankan; baris arahan shell mengandungi aksara[i], yang tidak dipadankan oleh ungkapan tersebut. Ia hanya membantu jika corak biasa tidak muncul di tempat lain pada baris itu: arahan permulaan semula kemudian pada baris yang sama akan dipadankan semula. - Cari, hentikan dan mulakan dalam panggilan SSH berasingan. Satu panggilan menyenaraikan proses dengan
pgrep -af, panggilan seterusnya membunuh PID yang dicetak, dan panggilan ketiga memulakan proses baharu. - Tunggu pada PID, bukan corak:
tail --pid=1234 -f /dev/null, atauwhile kill -0 1234; do sleep 30; done. - Lebih baik lagi, biar systemd yang memiliki kerja tersebut. Jalankannya sebagai unit dan tanya
systemctl is-active, atau mulakan dengansystemd-run --wait. Tiada corak yang boleh tersilap. - Setiap tunggu mempunyai tarikh akhir (
timeout 3h) dan menyatakan bila ia menyerah kalah. Gelung tanpa tarikh akhir gagal secara senyap.
Factory Floor, kit yang menjalankan mesin kami, berfungsi melalui unit systemd: ia tidak pernah mencari proses berdasarkan baris perintahnya. Gelung yang menyusahkan kami ialah yang kami taip secara manual.