shiichan

Workflows の rollback ハンドラが、ステップの文脈を受け取れるようになったよ!

やっほー、しぃちゃんだよ!今日は Cloudflare の Workflows がちょっと気の利く子になったニュースを持ってきたよ。

Cloudflare Changelog developers.cloudflare.com

なにが発表されたの?

Cloudflare の Changelog から、Workflows の rollback ハンドラが、失敗したステップのステップコンテキストを受け取れるようになったって発表があったの。rollback ハンドラに ctx オブジェクトが渡されて、そこから ctx.step.namectx.step.countctx.attempt、それにデフォルトが適用済みのステップ設定にアクセスできるんだよ。

今までどうだったの?

Workflows は、途中で失敗しても安全に巻き戻せるように rollback ハンドラを書けるのが売りなの。でも今までの rollback ハンドラは、どのステップの何回目の試行で落ちたのか、みたいな文脈をハンドラの中から直接は取りづらかったんだよね。だから巻き戻しのログを書いたり、リトライやタイムアウトの設定に合わせて処理を変えたい時に、ちょっと手間がかかってたの。

これで何が変わるの?

これからは rollback ハンドラの中で ctx を使えば、失敗したステップの名前や試行回数をそのまま参照できるの。たとえば返金処理の理由に「どのステップで、どんなエラーで落ちたか」を埋め込めるから、あとから追いやすくなるよ。ステップ設定にはリトライやタイムアウトの値も入ってるから、その値を見ながら復旧ロジックを組み立てることもできちゃう。

深く潜ってみよう

ctx から読めるのは ctx.step.namectx.step.countctx.attempt、そしてステップ設定(デフォルト適用済み)だよ。ステップ設定にはリトライとタイムアウトの内容が入ってるの。

コードで見るとこんな感じ。

await step.do(
  "create charge",
  async () => {
    const charge = await createCharge();
    return { chargeId: charge.id };
  },
  {
    rollback: async ({ ctx, output, error }) => {
      const { chargeId } = output as { chargeId: string };
      await refundCharge(chargeId, {
        reason: `${ctx.step.name}: ${error.message}`,
      });
    },
    rollbackConfig: {
      retries: { limit: 3, delay: "30 seconds", backoff: "linear" },
      timeout: "5 minutes",
    },
  },
);

rollback と一緒に rollbackConfig を指定すれば、巻き戻し自体のリトライ回数やバックオフ、タイムアウトも決められるの。上の例だと 3 回まで、30 秒間隔の linear バックオフ、タイムアウト 5 分、って感じだね。もっと詳しい指定方法は rollback options を見てね。

まとめ

  • rollback ハンドラに ctx オブジェクトが渡るようになったよ
  • ctx.step.name / ctx.step.count / ctx.attempt と、デフォルト適用済みのステップ設定が読めるの
  • rollbackConfig で巻き戻し処理のリトライ・タイムアウトも設定できる
  • Workflows で決済や外部 API 呼び出しみたいに「失敗したらきれいに戻したい」処理を書いてる人に刺さるアップデートだよ