Cloudflare Workflowsは、step retryのdelayへ関数を渡せるようになった。ctx.attemptとthrowされたerrorを使い、rate limitなら長く、短いnetwork failureなら短く待つ設計が可能になる。固定exponential backoffより柔軟だが、provider responseを無制限に信頼するとworkflowの滞留や重複処理を招く。

何が変わったか

step.doretries.delayは、duration string、millisecond numberに加え、次回delayを返すfunctionを受け付ける。functionはctxerrorを受け取り、string、number、またはそれらをresolveするpromiseを返せる。Retry-Afterやerror codeに応じたadaptive retryをWorkflow内で実装できる。

変更前後の差

従来はbase delayとconstantlinearexponential backoffを組み合わせるのが中心だった。変更後はfailure typeごとに異なる待機を選べる。ただしdynamic delayを使っても、retry limit、per-attempt timeout、stepのidempotencyは別途必要である。

誰に影響するか

外部SaaS API、LLM API、payment、notification、data warehouseへ接続するWorkflowが対象である。429、503、network timeoutを同じ例外として処理している実装は、error taxonomyを作り直す余地がある。

期限

強制移行期限はない。既存retry設定は継続できる。rate limitや長時間障害で無駄なretryが多いstepから段階的に変更する。

必要な対応

HTTP status、provider error code、Retry-After、network errorを正規化する。delayには最小・最大値を設け、jitterを加えてthundering herdを避ける。write operationにはidempotency keyを使い、retry後の二重作成を防ぐ。永久errorはretryせずdead-letter相当の処理へ送る。

実装・移行手順

  1. retry対象errorと非対象errorを分類する
  2. provider別のRetry-After形式をparseする
  3. delay calculationをpure functionとしてtestする
  4. minimum、maximum、jitterを設定する
  5. retry limitとtimeoutを合わせて見直す
  6. write stepへidempotency keyを追加する
  7. stagingで429、503、timeoutを注入する
  8. retry回数と完了時間を監視する

失敗しやすい点

error messageの文字列一致だけに依存する、巨大なRetry-Afterをそのまま採用する、promise rejectionを考慮しない、attempt numberの起点を誤る、writeを非idempotentなまま再試行する、といった問題が起きやすい。

リスク

retry storm、workflow滞留、外部API費用増加、二重決済・二重通知、timeout超過がある。dynamic functionが複雑になると、障害時に次回実行時刻を説明できなくなる。計算結果をstructured logへ残すべきである。

評価方法

  • error type別retry回数
  • successまでの平均attempt数
  • provider rate limit再発率
  • retry後の重複処理件数
  • workflow完了時間
  • maximum delay到達件数
  • permanent errorの誤retry率
  • 外部API request数と費用

ロールバック

dynamic functionをfeature flagで切り替え、問題時は既知の固定delayとexponential backoffへ戻す。進行中instanceへの影響を確認し、新規instanceだけ旧設定へ切り替える。重複処理が疑われる場合はdownstream recordをidempotency keyで照合する。

編集部分析

retryは可用性機能であると同時に、障害を増幅する機能でもある。dynamic delayの価値は待ち時間を賢くすることではなく、failure semanticsをcodeとして明示することにある。error分類、idempotency、observabilityがない状態で導入すると、挙動が読みにくくなるだけである。

実務チェックリスト

  • [ ] retry対象と永久errorを分類した
  • [ ] delayの最小・最大を設定した
  • [ ] jitterを追加した
  • [ ] writeをidempotentにした
  • [ ] 429・503・timeoutをtestした
  • [ ] delay計算をlogへ残す
  • [ ] 固定backoffへの切替を用意した

一次情報