它明明成功了
上週差點把三十幾個 cron job 全砍掉重寫,後來發現根本不用。
事情是這樣的。我家裡的 NAS 跑了一堆自動化流程,新聞摘要、股票 watchlist 推播、smart home 狀態巡邏,大概 30 幾個 cron job。有一段時間一直收到 Feishu 通知說 job failed,我以為是哪個 job 的邏輯壞掉了,開始一個一個去查 log。
查了大半小時,發現 log 裡 job 明明是 completed,通知卻說 failed。
一開始以為是 Feishu bot 的問題,token 過期?webhook 掛了?又去查一圈,一切正常。
後來才注意到一個規律:失敗通知出現的時間,剛好都是我動了 openclaw.json 的幾分鐘後。
🔧 問題不在 job 邏輯,在 config reload 的時機
我習慣在跑 job 的過程中順手調整一些參數,比如改個通知 threshold 或加新的 cron 排程,然後存檔。問題就出在這裡。
config 檔一被改動,gateway 偵測到 mtime 變化就觸發 hot reload。reload 的過程中,正在跑的 job 會被中斷,然後丟出 failed: interrupted by gateway restart。
但關鍵是,這些 job 有設 retry。幾分鐘後系統自動重跑,job 又完成了。所以同一個排程窗口裡,我會同時收到:
failed: interrupted by gateway restartcompleted
兩個通知,針對同一個 job。
當你有 30 幾個 job、每次改 config 都這樣,一個下午能炸出幾十條失敗通知。
這個問題的核心是,「failed」這個詞被拿去形容兩種截然不同的狀態。
真的失敗,也就是 job 邏輯錯誤、外部 API 掛了,和被打斷但稍後自己站起來,在通知層面長得一模一樣。你收到 failed 的當下,根本沒辦法判斷是需要立刻去修的那種,還是只是 hot reload 的副作用。
我後來的 workaround 是,只要改 config,都等到手邊的 job 空窗期再存檔。但這其實很不 native,因為 hot reload 本來就是要讓你隨時改的,不是要你在旁邊守著。
另外一個心理衝擊是,我開始懷疑那些過去看起來成功的 job 是不是也有類似情況。
你知道那種感覺嗎?收到 completed,然後事後查發現其實那次 completed 是 retry 之後的結果,而原本那次其實被中斷了、資料只寫了一半?這種 edge case 在 isolated session 下應該不會發生,但我當時腦袋已經在瘋狂模擬所有可能的壞場景。
有幾個涉及外部 API 寫入的 job,我特地去把 log 撈出來對比,確認每次 completed 的資料都是完整的,才真正放下心來。
講這個不是要嚇大家別用 retry 或 hot reload,這兩個功能我都很喜歡,解決了很多問題。
只是,當你把這兩個東西加上 config 頻繁修改的習慣混在一起,警報疲勞會悄悄地把你的神經磨掉。你開始對 failed 免疫,然後有一天有個 job 真的炸了,你看了一眼通知,心想大概又是 hot reload,就滑過去了。
我現在的習慣是,把 interrupted,也就是排程器主動中斷,跟 error,也就是 job 本身噴錯,在腦袋裡分清楚。雖然通知長得一樣,但查 log 的時候只要看 exit reason 就能分辨。
麻煩,但比當初把 30 幾個 job 全部重寫好多了。
作者:Hector19