生活分享

Claude Code|排程失敗怎麼辦:重複執行、漏跑與停止

為一次排程建立可追查且不重複寫入的工作。排程可靠性不只在於準時啟動,還包括重複觸發時不重複產生結果、失敗後知道從哪裡補跑,以及停止後能分辨已完成與未完成。本篇先把工作做成可手動重跑的本機程式,再選一個實際可用的排程入口接上它。

閱讀時間約 7 分鐘

排程失敗怎麼辦:重複執行、漏跑與停止:文件、螢幕與完成記號的幾何插圖
圖片:Mokaair (© Mokaair)
本篇目錄
  1. 先讓工作不靠排程也能完成
  2. 為一次工作設計穩定識別碼
  3. 寫入結果時處理鎖與原子替換
  4. 故障一:結果寫入前失敗
  5. 故障二:取消與異常中斷
  6. 最後才接上排程入口
  7. 漏跑與通知分開處理
  8. 區分工作結果與每次嘗試的狀態
  9. 完成判準與小練習

排程可靠性不只在於準時啟動,還包括重複觸發時不重複產生結果、失敗後知道從哪裡補跑,以及停止後能分辨已完成與未完成。本篇先把工作做成可手動重跑的本機程式,再選一個實際可用的排程入口接上它。

先讀、及。下載第 93 篇材料,開啟 starter。需要 Node.js 22,產品排程另需符合所選入口的條件。閱讀約 20 分鐘,實作約 45 分鐘。

先讓工作不靠排程也能完成

先讓工作不靠排程也能完成 → 為一次工作設計穩定識別碼 → 寫入結果時處理鎖與原子替換
先讓工作不靠排程也能完成 → 為一次工作設計穩定識別碼 → 寫入結果時處理鎖與原子替換 · 圖片:Mokaair (© Mokaair)
閱讀完整文字說明

排程失敗怎麼辦:重複執行、漏跑與停止,以流程和文件圖形呈現教學重點。

本課工作讀取 fixtures/tasks.json,統計總數與完成數,保存本機結果。它不呼叫模型、不連資料庫,也不寄送外部通知。先把資料處理、狀態與重試做好,再加入排程,才能分辨是工作本身失敗還是根本沒有被觸發。

專案終端機:第一次手動執行 · text
node automation/run-job.mjs daily-demo

預期 total=3、completed=1、reused=false。結果在 run-data/daily-demo.json;每次執行另有 attempts 下的狀態檔,run-state.json 是最後一次寫入的狀態摘要。摘要不取代完整歷史,並行時應以各 attempt 檔案及最終結果判斷。

狀態至少分 running、completed、failed、cancelled。沒有任何執行紀錄表示尚未觀察到啟動,不直接叫失敗。程序意外被終止可能留下 running,這表示需要核對程序與結果,不代表它現在仍真的在跑。

為一次工作設計穩定識別碼

daily-demo 是本次邏輯工作的 id;同一份輸入重跑相同 id,應重用完成結果。不同任務、日期或輸入版本應使用不同 id,但不能每次重試都隨機換 id,否則去重就沒有作用。attemptId 則辨識每一次嘗試,兩者用途不同。

材料計算輸入內容的 SHA-256 fingerprint。相同 id 但輸入變了會明確失敗,避免把舊結果套到新資料。這也讓你知道補跑是在恢復同一次工作,還是已經開始新的業務事件。

專案終端機:重跑同一份工作 · text
node automation/run-job.mjs daily-demo

第二次預期 reused=true,最終結果不再重做。若只看程序成功退出,無法知道它究竟重新計算還是重用,所以這個欄位和 fingerprint 都應保留。不要把重試成功直接解釋成第一次已成功,兩個 attempt 有自己的紀錄。

寫入結果時處理鎖與原子替換

job.mjs 先檢查已完成結果,再建立本機鎖目錄;取得鎖後重新核對結果是否已被其他執行者完成。真正結果先寫入唯一的暫存檔,再於同一資料夾重新命名成最終檔。這能避免讀者看到只寫了一半的 JSON。

鎖內保存程序識別與開始時間。若另一個程序已持有鎖,新的執行應停止並要求檢查,不直接刪除對方鎖。檔案鎖是本機課程策略,不是跨多台主機的分散式交易,也不保證所有外部 API 都只執行一次。

重新命名的行為依檔案系統與執行環境而定,本課使用同目錄的本機檔案。不要把這個做法無條件套到遠端物件儲存或網路共享,再宣稱有相同原子性。換環境時要重新確認儲存契約。

故障一:結果寫入前失敗

使用新的工作 id 加上 fail,程式會在最終結果產生前注入錯誤。預期非零退出,attempt 狀態為 failed,沒有合法最終結果。正常的錯誤分支會釋放自己取得的鎖,讓相同工作可以補跑。

專案終端機:故障與補跑使用同一 id · text
node automation/run-job.mjs recover-demo fail
node automation/run-job.mjs recover-demo
node automation/run-job.mjs recover-demo

三次結果應依序是失敗、首次完成、重用完成。查看 attempts 紀錄確認順序與原因,再核對 recover-demo.json 的資料。不能只保留最後一次成功,因為故障與恢復正是這篇要驗證的流程。

若最終檔已存在卻內容損壞,先保存故障證據並確認來源,不把它當成合法完成結果。需要重建時,使用自己的備份或明確的新工作 id;不要無聲覆蓋讀者可能需要追查的舊結果。

故障二:取消與異常中斷

pause 模式在真正開始資料工作前等待十秒,方便讀者按 Ctrl+C。程式會把這次 attempt 標為 cancelled 後結束。這是可控的取消示例,不會在等待期間對外部系統產生副作用。

專案終端機:執行後在等待中按 Ctrl+C · text
node automation/run-job.mjs cancel-demo pause

檢查 run-state.json 與對應 attempt,預期取消且沒有 cancel-demo 的最終結果。若使用強制結束程序,可能來不及寫取消狀態,留下 running;這時需核對 pid 是否仍存在、鎖及結果檔,而不是直接相信狀態文字。

對殘留鎖,不要只因開始時間很久就刪除。先確認它屬於這個練習、原程序已不在、沒有合法結果仍在寫入,保存鎖內容後才處理。無法確認時先停止補跑,避免兩個程序同時寫同一結果。

最後才接上排程入口

選擇你帳號支援的 CLI、桌面或雲端排程,記錄實際主機、工作目錄、觸發時間及持久性。CLI 工作階段內的重複提示需要該階段保持運作;桌面本機任務需要電腦與 App 符合條件;雲端工作則要把材料與依賴放到雲端可讀的位置。

可以先安排一次短期測試,要求在指定 starter 執行固定的 run-job 命令,完成後回報結果位置與退出狀態。建立後查看實際任務清單及下一次時間,觸發後核對 attempt 檔案,再停用這次測試排程。不要以自然語言說「每天做」就推定系統真的保存了排程。

所選排程入口的任務內容:路徑依自己的環境設定 · text
在已指定的 starter 專案執行 node automation/run-job.mjs scheduled-demo。
只處理本機假資料,回報退出狀態及最終結果位置。
相同工作 id 不重複產生結果;失敗保留 attempt 紀錄。
不要寄信、推送、合併或部署。

這個固定 id 用於測試重複觸發;正式每日工作應有日期及輸入版本策略。日期要指定時區,不能一部分用 UTC、一部分用本地日期而產生兩個不同 id。每個入口的排程能力請回到官方文件與核對。

漏跑與通知分開處理

沒有 attempt 紀錄時,先查排程是否觸發、主機是否運作與工作目錄是否正確。已有 failed 紀錄則查工作錯誤。已有 completed 但沒有通知,查的是通知流程,不能重新執行業務工作來補一個提醒。

觀察判讀與處理
沒有執行紀錄查觸發與主機,不直接判成程式失敗
failed 且無最終結果保存原因,以同 id 恢復
running 但 pid 已不存在視為中斷待核對,檢查鎖與結果
completed 且通知失敗只重送通知,不重做工作
相同 id 但輸入不同改用正確的新工作識別,不套舊結果

區分工作結果與每次嘗試的狀態

同一個工作識別碼可能有多次嘗試,各自需要開始時間與結束狀態。已完成的結果可以被後續嘗試重用,但前一次失敗的紀錄仍應保留,否則會低估實際成本。本課以不同 attemptId 保存紀錄,最後狀態檔只是方便查看的摘要。

程序被強制終止時可能來不及寫入 cancelled,因此看到 running 不代表它一定仍在運作。先核對程序與工作結果,保存現場資料後再處理鎖檔,避免另一個執行者還在工作時被重複啟動。

完成判準與小練習

交付 id 設計、狀態檔、重複執行、故障補跑、取消及一個實際排程觸發紀錄。尚未接產品排程時,寫明本機 runner 完成、排程待測。停止後確認測試排程已停用,避免教材練習留下持續執行的工作。

小練習是改動一筆 completed 後用相同 id 重跑,確認被 fingerprint 檢查拒絕,再設計新 id 完成另一份結果。接下來進入,分清楚模型工作階段接續與業務工作去重的不同責任。

回總目錄

  • 生活分享

    Claude Code|建立第一個 mod:在 Claude Code 行程內數工具呼叫

    寫一個三檔案的 mod,用驗證器與測試確認它掛上的事件。文件把 mod 定義成多了入口檔的 plugin:入口檔叫 hooks module,Claude Code 在事件發生時呼叫裡面的函式,函式可以觀察、改寫或接手事件。

  • 生活分享

    Claude Code|Git Worktree 平行工作

    隔離多個任務的檔案與分支。Git Worktree 讓同一儲存庫擁有多個工作目錄,各自使用分支與檔案。本篇會把待辦篩選與文件整理分開,確認兩個 session 不會直接改到彼此的檔案,再把其中一個成果整合回主分支。你也會知道何時可以安全清理工作目錄。

  • 生活分享

    Claude Code|雙 Worktree 實作與衝突整合

    隔離兩項功能,最後完成整合與回歸。兩個 Claude 工作階段同時編輯專案,最容易出現的問題是互相改到同一份檔案,或各自測試通過、整合後卻失敗。本篇用兩個 Worktree 分別處理篩選預設值與介面文字,故意製造一次小衝突,再完成整合、驗證與清理。你不需要先啟用 Agent Teams。

  • 生活分享

    Claude Code|比較流程品質、用量與執行時間

    以同一資料集比較兩種工作方法。比較兩種 Claude 工作方法時,不能只挑成功那一次,也不能只看第一個答案有多快。本篇用固定案例、原始紀錄和一致判準,比較品質、重試、等待與人工整合時間,最後寫出有樣本數與限制的報告,而不是保證某個方法一定省錢。

最新旅遊情報攻略

資料來源

生活分享