ActiveSupport::TimeFormats のラムダを Ractor 共有可能にする

rails/rails

ActiveSupport::TimeFormats が保持する日時フォーマット用ラムダを、Ractor 環境でも安全に共有できるよう変更しました。機能的な変更はなく、既存コードはそのまま動作します。

背景

Ractor はオブジェクトの安全な共有を提供しますが、標準の Proclambda はデフォルトで共有不可です。ActiveSupport::TimeFormats@list ハッシュに複数のフォーマット用ラムダを保持しており、Ractor 内でこれらを参照すると Ractor::IsolationError が発生していました。既存の long_ordinalrfc822rfc2822iso8601 などのキーは直接 lambda { |time| … } で定義されていました。

技術的な変更

対象となるラムダを ActiveSupport::Ractors.shareable_lambda でラップするだけの置換が行われました。変更前後のコードは以下のとおりです。

変更前:

long_ordinal: lambda { |time|
  day_format = ActiveSupport::Inflector.ordinalize(time.day)
  time.strftime("%B #{day_format}, %Y %H:%M")
},
rfc822: lambda { |time|
  offset_format = time.formatted_offset(false)
  time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}")
},
rfc2822: lambda { |time| time.rfc2822 },
iso8601: lambda { |time| time.iso8601 }

変更後:

long_ordinal: ActiveSupport::Ractors.shareable_lambda { |time|
  day_format = ActiveSupport::Inflector.ordinalize(time.day)
  time.strftime("%B #{day_format}, %Y %H:%M")
},
rfc822: ActiveSupport::Ractors.shareable_lambda { |time|
  offset_format = time.formatted_offset(false)
  time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}")
},
rfc2822: ActiveSupport::Ractors.shareable_lambda { |time| time.rfc2822 },
iso8601: ActiveSupport::Ractors.shareable_lambda { |time| time.iso8601 }

ActiveSupport::Ractors.shareable_lambdaactivesupport/lib/active_support/ractors.rb に定義されており、Ruby のバージョンに応じて Ractor.shareable_lambda へ委譲するか、単にブロックを返す実装になっています。このラッパーを通すだけで、元のラムダのロジックは変わらず、Ractor で安全に共有できるようになります。

設計判断

新たな設定キーや API を追加せず、既存の @list エントリをラップすることで後方互換性を最大化しました。ActiveSupport::Ractors.shareable_lambda を中心に実装を集約することで、Ruby バージョン間の差異を内部で吸収し、Ractor の有無に関わらず同一コードベースで動作します。外部からは変更を意識する必要がなく、他モジュールへの波及効果も抑えられています。

まとめ

この PR は ActiveSupport::TimeFormats に格納された日時フォーマット用ラムダを Ractor 共有可能 に変換し、マルチスレッド環境での安全性を向上させました。振る舞いはそのままで、API 互換性も維持されているため、今後の Ractor 活用の基盤として利用できます。

  • Primary Source: #57857
  • Generated by: gpt-oss-120b for DiffDaily

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
4114d6ff

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

品質レビュー結果

Review Status:
リトライ後承認
Review Count:
2回 (改善を経て承認)
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

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

リード文、背景、技術的な変更、設計判断、まとめの5つの必須セクションが揃っており、総論→各論→結論の流れが明確です。

カスタムMarkdown構文 ✓ PASS

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

コードブロックは `ruby:ファイルパス` 形式で正しく記述され、PRリンクは `[#57857](URL)` の形式で正しくハイパーリンク化されています。

対象読者への適合性 ✓ PASS

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

エンジニア向けの技術的内容で、初心者向けの過度な説明はありません。

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

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

各セクションは総論・各論・結論の段落構成で、トピックセンテンスが先頭にあり、1段落1トピック・適切な長さが保たれています。

Diff内容との照合 ✓ PASS

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

記事中の before/after のコードブロックは提供された Diff と完全に一致し、変更点が正確に反映されています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

Ractor、shareable_lambda、ActiveSupport::Ractors などの用語は PR と一致し、誤用はありません。

説明の技術的正確性 ✓ PASS

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

ラップするだけで動作が変わらない旨や後方互換性への配慮など、説明は PR の意図と合致しています。

事実の突合 ✓ PASS

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

記事のすべての主張は PR タイトル・説明・Diff で裏付けられており、推測や捏造はありません。

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

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

PR 番号 #57857 などの固有名詞は正確です。

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

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

記事タイトルは PR タイトルの意味を正しく日本語化しており、一致しています。

外部知識の正確性 ✓ PASS

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

バージョンサポートやリリース日程など、PR に無い外部知識は含まれていません。

時間表現の正確性 ✓ PASS

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

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