`retry_on` の `wait:` プロックで省略引数を受け付けるよう修正

rails/rails

retry_on のオプション wait: に渡す Proc が省略引数を持つ場合でも正しく呼び出せるよう、Arity 判定ロジックが改良されました。これにより、既存の 1 引数 Proc と同様にオプション引数付き Proc もエラーなく利用でき、バックグラウンドジョブのリトライスケジュール設定の柔軟性が向上します。

背景

ActiveJob のリトライ機構は wait:Proc を指定でき、実行回数や例外情報に基づく遅延時間を算出します。従来は algorithm.arity == 1 の場合に 1 引数で、以外は 2 引数で呼び出す実装で、arity が -1(省略引数付き Proc)でも 2 引数で呼び出され ArgumentError が発生していました。

この問題は、->(executions = 0) { … } のように引数にデフォルト値を設定した Proc が対象です。テストケースが追加されるまで実運用での障害は顕在化しにくく、PR では 1 本のプロダクションラインで例外が報告されたことが発端となっています。

技術的な変更

activejob/lib/active_job/exceptions.rbdetermine_delay メソッドで、Arity 判定式が以下のように変更されました。

変更前:

algorithm.arity == 1 ? algorithm.call(executions) : algorithm.call(executions, error)

変更後:

algorithm.arity == 2 || algorithm.arity < -1 ? algorithm.call(executions, error) : algorithm.call(executions)

新条件は次の 2 つを評価します。① arity が 2 の場合(明示的に 2 引数を受け取る Proc)② arity が -1 未満 の場合(省略引数や可変長引数 *rest を含む Proc)。この判定により、->(executions = 0)->(executions, *rest) でも適切に 1 引数で呼び出されます。

テストコードも同時に拡充され、activejob/test/jobs/retry_job.rbOptionalArgWaitError 用の retry_on 定義が追加され、activejob/test/cases/exceptions_test.rb に新しいテスト "custom wait proc with an optional argument" が実装されました。テストは travel_to で時刻を固定し、期待されるスケジュール時刻が正しく記録されることを検証しています。

設計判断

この修正は API を増やさず既存の retry_on オプションだけで対応 するという方針の下で実装されました。代替案としては wait: 用に別のキー(例: wait_with_options:)を導入する案が議論されましたが、後方互換性と既存コードへの影響最小化の観点から、Arity 判定ロジックの拡張が選択されました。

判定ロジックは 「arity が 2 もしくは -1 未満」 というシンプルな式にまとめられ、可読性を保ちつつ省略引数・可変長引数の両方を包括的に扱えるようになりました。これにより、開発者は wait: に自由な Proc を記述でき、リトライ遅延の計算ロジックをより表現力豊かに記述可能です。

まとめ

retry_onwait: プロックが省略引数を受け取るケースを考慮した Arity 判定へ改良されたことで、ArgumentError が除去され、既存のリトライ設定と互換性を保ちつつ新たな柔軟性が提供されました。テストも追加されているため、今後のリリースで安定した挙動が保証されます。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
68c08a95

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文、背景、技術的変更、設計判断(任意)、まとめが揃っており、総論→各論→結論の流れが明確です。

カスタムMarkdown構文 ⚠ WARNING

シンタックスハイライト・GitHubリンク記法の正確性

コードブロックは正しい `ruby:ファイルパス` 形式ですが、PRリンクが `[PR #57723](URL)` という記述で、仕様で求められる `[ #57723](URL)` の形式と完全には一致していません。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

内容はActiveJobやRubyに精通したエンジニア向けで、初心者向けの余計な説明はありません。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションは総論パラグラフ→各論パラグラフ→結論パラグラフで構成され、段落は1文で要点が示され、長すぎる段落や複数トピックはありません。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内のコードブロックはDiffの変更前後と完全に一致しており、ファイル名もDiffと合致しています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

使用されている技術用語はPRで示されたものと一致しており、誤用は見られません。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

変更理由、実装内容、影響範囲の説明はPRの記述と整合しており、技術的に正確です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事の全主張はPRタイトル・説明・Diffで裏付けられており、根拠のない推測や矛盾はありません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号やファイルパス、コード中の数値は正確に記載されています。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事タイトルはPRの内容を日本語で適切に要約しており、一致しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事内にPRに記載されていない外部知識(LTS、リリース日程等)は含まれていません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

時間表現の歪曲はなく、PRの記述と一致しています。