ActionView の view_context_class 初期化を早期化し Ractor 共有を実現

rails/rails

この PR は enable_reloading が無効なケースで不要なミューテックス取得を削減し、Ractor 環境で view_context_class をそのまま共有できるようにします。結果としてスレッド競合を減らしつつ、Ractor 用の追加設定を不要にします。

背景

この変更は enable_reloading が無効な場合に不要なミューテックス取得を排除し、Ractor 環境での view_context_class の共有を可能にすることを目的としています。従来、view_context_class は毎回 @view_context_mutex.synchronize 内で初期化され、リロードが無効でもロックが発生していました。さらに、Ractor から直接参照できないことがテストで指摘されており、追加のセットアップが必要でした。

技術的な変更

actionview/lib/action_view/lookup_context.rb では view_context_class の取得ロジックを刷新し、既にインスタンスが存在すればロックを回避してすぐに返すようにしました。

@@
-    def self.view_context_class
-      @view_context_mutex.synchronize do
-        @view_context_class ||= ActionView::Base.with_empty_template_cache
-      end
-    end
+    def self.view_context_class
+      return @view_context_class if @view_context_class
+      base = ActionView::Base # prevent recursive locking
+      @view_context_mutex.synchronize do
+        @view_context_class = base.with_empty_template_cache
+      end
+    end

reset_view_context_class を新たに導入し、clear 時にミューテックスで安全にインスタンスをリセットできるようにしました。

@@
-    def self.clear
+    def self.clear
@@
-        @view_context_class = nil
+        ActionView::LookupContext.reset_view_context_class

ミューテックス本体はメソッド定義の後方に遅延初期化し、ActiveSupport.on_load(:action_view) フックでロード時に view_context_class を先行取得させることで、Ractor がクラスを共有できる状態にします。

@@
-    @view_context_mutex = Mutex.new
-    ActiveSupport.on_load(:action_view) { ActionView::LookupContext.view_context_class }
+    @view_context_mutex = Mutex.new
+    ActiveSupport.on_load(:action_view) { ActionView::LookupContext.view_context_class }

actionview/lib/action_view/rendering.rb の参照先を LookupContext に統一し、view_context_class の取得が一元化されました。

@@
-        klass = ActionView::LookupContext::DetailsKey.view_context_class
+        klass = ActionView::LookupContext.view_context_class

テスト actionview/test/template/lookup_context_test.rb に Ractor 用の検証が追加され、view_context_class が Ractor 間で同一オブジェクトであることが保証されました。

if RUBY_VERSION >= "4.0"
  class LookupContextRactorTest < ActiveSupport::TestCase
    include ActiveSupport::Testing::Isolation

    test "view_context_class is Ractor-shareable" do
      @original_experimental_warning = Warning[:experimental]
      Warning[:experimental] = false
      ActionView::LookupContext.view_context_class # eager-load
      assert_same ActionView::LookupContext.view_context_class,
        Ractor.new { ActionView::LookupContext.view_context_class }.value
    ensure
      Warning[:experimental] = @original_experimental_warning
    end
  end
end

設計判断

view_context_class の取得を LookupContext に集約し、早期リターンでロック回避を実装したことで、不要な同期コストを排除しつつ既存のスレッド安全性は保持されています。reset_view_context_class を公開し clear から呼び出す設計は、状態リセットを一元管理できる点で拡張性を高めています。ActiveSupport.on_load フックの追加は、Ractor がクラスをロードするタイミングを保証し、追加のセットアップなしで共有可能にした実用的な選択です。

まとめ

view_context_class の初期化を早期化しロック取得を回避した本変更は、enable_reloading が無効な場合でもパフォーマンスを向上させ、Ractor で安全に共有できるようにしました。設計上は既存 API 互換を保ちつつ、リセットロジックとロードフックで拡張性と並行性を両立させています。

記事メタデータ

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

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

品質レビュー結果

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

Review Criteria:

記事構成 ✓ PASS

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

リード文がタイトル直下にあり、背景・技術的変更・設計判断・まとめの各セクションが揃っているため、総論→各論→結論の構成が明確です。

カスタムMarkdown構文 ✓ PASS

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

ファイル名付きコードブロックは ```ruby:actionview/... の形式で正しく記述され、PRリンクも [PR #57823](URL) という形式で正しくリンク化されています。

対象読者への適合性 ✓ PASS

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

内容は Rails の内部実装に詳しいエンジニア向けで、基礎的な解説や初心者向けの余計な情報はありません。

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

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

各セクションは総論パラグラフ→各論パラグラフ→結論パラグラフで構成され、段落はトピックセンテンスで始まり 1段落1トピック、文量も適切です。空行で区切られています。

Diff内容との照合 ✓ PASS

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

記事中のコードブロックは全て Diff に記載された変更と一致しており、抜粋・改変の不整合はありません。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

view_context_class、Mutex、Ractor、enable_reloading などの用語は PR の記述と一致し、誤用は見られません。

説明の技術的正確性 ✓ PASS

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

「ミューテックス取得を回避」「Ractor で共有可能にする」等の主張は Diff と PR の説明に裏付けられ、技術的に正確です。

事実の突合 ✓ PASS

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

記事の全ての事実は PR タイトル・説明・Diff に基づいており、根拠のない推測や外部知識の付加はありません。

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

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

PR 番号 #57823 が正しく記載され、他に数値・固有名詞の誤りはありません。

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

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

記事タイトルは PR の意図(view_context_class の早期初期化)を適切に日本語化して表現しています。

外部知識の正確性 ✓ PASS

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

LTS やリリース日程など、PR に記載のない外部情報は一切含まれていません。

時間表現の正確性 ✓ PASS

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

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