ਸਾਡਾ ਵੇਟ ਲੂਪ ਆਪਣੇ ਆਪ ਲਈ 35 ਘੰਟੇ ਉਡੀਕਿਆ: SSH ਉੱਤੇ pgrep -f ਅਤੇ pkill -f
Ops
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 ਮਿੰਟ ਤੱਕ ਇੱਕ ਟ੍ਰਾਂਸਲੇਸ਼ਨ ਕਿਊ ਨੂੰ ਫੜ ਕੇ ਰੱਖਿਆ, ਅਤੇ ਇਹ ਵਾਲਾ।
ਹੁਣ ਅਸੀਂ ਕੀ ਕਰਦੇ ਹਾਂ
- ਪੈਟਰਨ ਵਿੱਚ ਬ੍ਰੈਕਟ:
pgrep -f "[i]18n_job.py example.com"। ਇੱਕ ਰੈਗੂਲਰ ਐਕਸਪ੍ਰੈਸ਼ਨ ਵਜੋਂ,[i]ਅੱਖਰ i ਨਾਲ ਮੇਲ ਖਾਂਦਾ ਹੈ, ਇਸ ਲਈ ਜੌਬ ਅਜੇ ਵੀ ਮੈਚ ਕਰਦੀ ਹੈ; ਸ਼ੈੱਲ ਦੀ ਕਮਾਂਡ ਲਾਈਨ ਵਿੱਚ ਅੱਖਰ[i]ਹੁੰਦੇ ਹਨ, ਜਿਨ੍ਹਾਂ ਨਾਲ ਐਕਸਪ੍ਰੈਸ਼ਨ ਮੈਚ ਨਹੀਂ ਕਰਦਾ। ਇਹ ਸਿਰਫ਼ ਤਦ ਹੀ ਮਦਦ ਕਰਦਾ ਹੈ ਜੇਕਰ ਸਧਾਰਨ ਪੈਟਰਨ ਉਸ ਲਾਈਨ ਉੱਤੇ ਕਿਤੇ ਹੋਰ ਨਾ ਆਉਂਦਾ ਹੋਵੇ: ਉਸੇ ਲਾਈਨ ਵਿੱਚ ਬਾਅਦ ਵਿੱਚ ਇੱਕ ਰੀਸਟਾਰਟ ਕਮਾਂਡ ਦੁਬਾਰਾ ਮੈਚ ਕਰ ਲਵੇਗੀ। - ਵੱਖ-ਵੱਖ SSH ਕਾਲਾਂ ਵਿੱਚ ਲੱਭੋ, ਰੋਕੋ ਅਤੇ ਸ਼ੁਰੂ ਕਰੋ। ਇੱਕ ਕਾਲ
pgrep -afਨਾਲ ਪ੍ਰੋਸੈੱਸਾਂ ਦੀ ਸੂਚੀ ਦਿੰਦੀ ਹੈ, ਅਗਲੀ ਉਹਨਾਂ ਦੇ ਪ੍ਰਿੰਟ ਕੀਤੇ PIDs ਨੂੰ ਮਾਰ ਦਿੰਦੀ ਹੈ, ਤੀਜੀ ਨਵਾਂ ਪ੍ਰੋਸੈੱਸ ਸ਼ੁਰੂ ਕਰਦੀ ਹੈ। - ਪੈਟਰਨ ਉੱਤੇ ਨਹੀਂ, PID ਉੱਤੇ ਉਡੀਕ ਕਰੋ:
tail --pid=1234 -f /dev/null, ਜਾਂwhile kill -0 1234; do sleep 30; done। - ਹੋਰ ਵਧੀਆ, ਜੌਬ ਨੂੰ systemd ਦੇ ਅਧੀਨ ਰਹਿਣ ਦਿਓ। ਇਸਨੂੰ ਇੱਕ ਯੂਨਿਟ ਵਜੋਂ ਚਲਾਓ ਅਤੇ
systemctl is-activeਨਾਲ ਪੁੱਛੋ, ਜਾਂsystemd-run --waitਨਾਲ ਸ਼ੁਰੂ ਕਰੋ। ਇਸ ਵਿੱਚ ਕੋਈ ਗਲਤੀ ਹੋਣ ਵਾਲਾ ਪੈਟਰਨ ਨਹੀਂ ਹੈ। - ਹਰ ਇੰਤਜ਼ਾਰ ਦਾ ਇੱਕ ਡੈੱਡਲਾਈਨ ਹੁੰਦਾ ਹੈ (
timeout 3h) ਅਤੇ ਇਹ ਦੱਸਦਾ ਹੈ ਕਿ ਇਹ ਕਦੋਂ ਹਾਰ ਮੰਨ ਲਵੇਗਾ। ਬਿਨਾਂ ਡੈੱਡਲਾਈਨ ਵਾਲਾ ਲੂਪ ਚੁੱਪ-ਚਾਪ ਫੇਲ੍ਹ ਹੋ ਜਾਂਦਾ ਹੈ।
Factory Floor, ਉਹ ਕਿੱਟ ਜੋ ਸਾਡੀਆਂ ਮਸ਼ੀਨਾਂ ਚਲਾਉਂਦੀ ਹੈ, systemd ਯੂਨਿਟਾਂ ਰਾਹੀਂ ਕੰਮ ਕਰਦੀ ਹੈ: ਇਹ ਕਦੇ ਵੀ ਕਮਾਂਡ ਲਾਈਨ ਦੁਆਰਾ ਪ੍ਰੋਸੈੱਸ ਨੂੰ ਨਹੀਂ ਲੱਭਦੀ। ਉਹ ਲੂਪ ਜਿਨ੍ਹਾਂ ਨੇ ਸਾਨੂੰ ਫਸਾਇਆ ਸੀ, ਉਹੀ ਸਨ ਜਿਨ੍ਹਾਂ ਨੂੰ ਅਸੀਂ ਹੱਥੀਂ ਟਾਈਪ ਕੀਤਾ ਸੀ।