Skip to Content
核心概念觸發器執行紀錄與重試

Trigger runs 與單次重試

每次 trigger 命中都會留下可觀測的 run。來源寫入成功不等於 actions 成功;產品端應以 run status 作為 automation 的真實狀態,並保留能讓 operator 找到來源 record 與失敗 action 的關聯。

列出 runs

curl \ "$BASE_URL/private/module/custom_tables/chatroom/11111111-1111-4111-8111-111111111111/tables/22222222-2222-4222-8222-222222222222/trigger-runs?status=failed&skip=0&limit=50" \ -H "Authorization: Bearer $TOKEN"

可篩選 pending、running、done、failed、stuck,並用 skip / limit 分頁。每筆 run 的關鍵欄位包括:

欄位用途
id, trigger_id, event, table_id, record_id對應設定與來源列;table-level schedule 的 record_id 可為 null
record_version, payload觸發當下的版本與 snapshot(其中的 data 與 diff 使用內部 col_<hex> 鍵),不是目前列的即時值
status, attempts, error生命週期與最後錯誤
action_results每個 action 的成功或失敗結果
chain_id, depth追蹤衍生 automation chain;chain 的 generated-run 計數器是內部欄位,不會回傳

stuck 是列表篩選條件,不是儲存的狀態:它回傳所有 failed run,加上 updated_at 已超過 300 秒的 running run(worker 已崩潰)。不要只靠頁面上的 running 字樣判斷它仍健康。完整 response model 見 triggerRuns.list。

對一筆 run 重試

Table moderator 可對 failed、pending 或已 stale 的 running run 呼叫:

curl -X POST \ "$BASE_URL/private/module/custom_tables/chatroom/11111111-1111-4111-8111-111111111111/tables/22222222-2222-4222-8222-222222222222/trigger-runs/33333333-3333-4333-8333-333333333333/retry" \ -H "Authorization: Bearer $TOKEN"

成功會把狀態重設為 pending 並清除 top-level error。Retry 採 resume 語意:action_results 中已成功的 action 不會重跑,worker 從第一個未成功 action 繼續。同時送達的重複 delivery 會輸掉原子 pending → running claim,在沒有額外副作用的情況下退出。這能避免重複通知或重複外部寫入,但外部 action 本身在 post-effect/pre-receipt 崩潰視窗內仍應設計 idempotency。

續跑是用 action 的穩定 action_id 去比對先前的 receipt,不是用它在清單中的位置,所以在一次 run 失敗到重試之間插入或重排 action,不會把已完成的 receipt 錯位到別的 action 上。只有兩種情況會退回用位置續跑:action id 出現之前寫下的舊紀錄,以及紀錄中的 id 已經對不上任何現有 action id 的情況——用戶端存 trigger 時沒有把每個 action 回傳的 id 原樣送回、所有 id 都被重新產生時就會發生。依位置續跑只有在 action 沒有同時被插入或重排時才安全。若只有部分 id 被重新產生,那些 action 找不到 receipt,會再執行一次。

造成觸發的寫入 commit 之後,每個 run 會交給伺服器設定的背景 worker;不能依請求或依 trigger 選擇。依該 worker 而定,送達是至少一次(重複的那一份會輸掉原子 claim)或最多一次(執行途中 pod 重啟,就只能交給 requeue 清掃處理)。排入佇列失敗只會留下紀錄,由清掃把 run 救回來。

重試執行哪一份定義,取決於 run 的來源。Row-event run(created、updated、deleted、restored)每次嘗試都會重新讀取目前的 trigger 設定,所以在這種 run 處於 failed 時修改 trigger,會改變重試實際執行的內容。Schedule run 則重新執行建立時凍結進 run 的 trigger 定義 — 目前的 schema、權限、SCP 與目標是否存在仍會重新驗證,但對 live trigger 的修改只影響未來的 schedule run,刪除 trigger 也不會讓重試失敗。在 snapshot 機制出現之前建立的 schedule run 維持 row-event 的行為。重試 interval、daily 或 cron run 還會重新武裝該 trigger 的「同時只有一個 run」fence;當同一 trigger 仍有另一個 run 在 pending 或 running 時,會回 409 another run is active for this schedule trigger; retry after it completes。詳見排程觸發器。

done 或仍活躍的 running run 會回 409,不存在或不屬於這張表則 404。UI 應在 retry 後重新輪詢該 run,而不是先假設成功。

Note 這個端點是 moderator 對單一已知 run 的產品操作。遺失 enqueue 或 stale workers 的復原屬於平台工作:每一次 root scheduler tick 都已經會重新送出超過 300 秒的 pending run 與 stale 的 running run(每次最多 500 筆),operator requeue 則可隨時執行同一套掃描。兩者都不會撿起 failed run,用戶端也絕不該改用迴圈呼叫單次 retry。

端點細節見 triggerRuns.retry。

Lock 衝突會在 run 內部重試

短暫的資料庫 lock 衝突不再讓一次 run 失敗。Worker 會就地重試這些 action——上限三次嘗試,搭配帶 jitter 的退避——只有每次都失敗才把 run 記為 failed。

這個重試之所以安全,正是上面那套續跑理由:進度逐個 action 持久化,已完成的 receipt 以穩定的 action_id 比對,所以 run 內部的重試會從第一個未成功的 action 繼續,而不會重跑已經成功的副作用。invoke_command action 若從 command 執行收到可重試的衝突,也以同樣方式重試並沿用同一個 idempotency key;這是合法的,因為該失敗會釋放這個 key 的保留。

值得知道的是排程類 action。以前只要一次短暫衝突,run 就會停在 failed、attempts: 1,而業務動作被無聲丟掉——一個每日排程那天就是沒做事,除了那列 run 之外沒有任何跡象。這類 action 現在會在同樣的上限內重試。

不可重試的錯誤維持原樣:它們一如既往地讓 run 失敗,moderator 重試仍是復原路徑。哪些資料庫錯誤算短暫,見併發與 lock 衝突。

Last updated on