バックトレースクリーンナーをデフォルトでRactor共有可能に

rails/rails

Rails のバックトレースクリーンナーが、デフォルトフィルタおよびサイレンサーを Ractors.shareable_proc でラップすることで、Rails.application 全体を Ractor に渡す際の共有エラーを解消します。

背景

Rails.application を Ractor に移行すると、内部で保持している Proc オブジェクト が非共有オブジェクトとなり、Ractor.make_shareable が失敗します。バックトレースクリーンナーはデフォルトで複数のフィルタとサイレンサーを持つため、手動で共有可能に変換する手間が発生していました。この PR は、デフォルト実装だけで共有可能にし、開発者が追加の設定を行わなくても Ractor 化できるようにすることを目的としています。

技術的な変更

ActiveSupport::BacktraceCleaner の変更

add_gem_filteradd_core_silenceradd_gem_silenceradd_stdlib_silencer が、従来のブロックを Ractors.shareable_proc でラップした形に書き換えられました。これにより、各フィルタ・サイレンサーが Ractor 共有可能な Proc として登録されます。

- add_filter { |line| line.sub(gems_regexp, gems_result) }
+ add_filter(&Ractors.shareable_proc { |line| line.sub(gems_regexp, gems_result) })
@@
- add_silencer { |line| line.include?("<internal:") }
+ add_silencer(&Ractors.shareable_proc { |line| line.include?("<internal:") })
@@
- add_silencer { |line| FORMATTED_GEMS_PATTERN.match?(line) }
+ add_silencer(&Ractors.shareable_proc { |line| FORMATTED_GEMS_PATTERN.match?(line) })
@@
- add_silencer { |line| line.start_with?(RbConfig::CONFIG["rubylibdir"]) }
+ add_silencer(&Ractors.shareable_proc { |line| line.start_with?(RbConfig::CONFIG["rubylibdir"]) })

Rails::BacktraceCleaner の変更

initialize メソッド内で追加されるカスタムフィルタとサイレンサーが ActiveSupport::Ractors.shareable_proc でラップされました。さらに、root の取得ロジックをクラスメソッドに切り出し、freeze 時に参照を確保することで、遅延評価の影響を抑制しています。

@@
- add_filter do |line|
-   @root ||= Rails.root && "#{Rails.root}/"
-   @root && line.start_with?(@root) ? line.from(@root.size) : line
- end
+ add_filter(&ActiveSupport::Ractors.shareable_proc do |line|
+   BacktraceCleaner.root && line.start_with?(BacktraceCleaner.root) ? line.from(BacktraceCleaner.root.size) : line
+ end)
@@
- add_filter do |line|
-   if RENDER_TEMPLATE_PATTERN.match?(line)
-     line.sub(RENDER_TEMPLATE_PATTERN, "")
-   else
-     line
-   end
- end
+ add_filter(&ActiveSupport::Ractors.shareable_proc do |line|
+   if RENDER_TEMPLATE_PATTERN.match?(line)
+     line.sub(RENDER_TEMPLATE_PATTERN, "")
+   else
+     line
+   end
+ end)
@@
- add_silencer do |line|
-   line.start_with?(File::SEPARATOR, "vendor/", "bin/")
- end
+ add_silencer(&ActiveSupport::Ractors.shareable_proc do |line|
+   line.start_with?(File::SEPARATOR, "vendor/", "bin/")
+ end)

テストの追加

ActiveSupport::Testing::RactorsAssertions モジュールで assert_ractor_shareable ヘルパーが導入され、BacktraceCleanerDefaultFilterAndSilencerTestBacktraceCleanerTest に共有可能性を検証するテストが追加されました。テストは Ruby 4.0 以上では実際に Ractor.make_shareable を呼び出し、例外が起きないことを確認します。

module ActiveSupport
  module Testing
    module RactorsAssertions # :nodoc: all
      private
        if RUBY_VERSION >= "4.0"
          def assert_ractor_shareable(obj)
            assert_nothing_raised { Ractor.make_shareable(obj) }
          end
        else
          def assert_ractor_shareable(obj)
            assert true
          end
        end
    end
  end
end

設計判断

デフォルト実装に対してのみ Ractors.shareable_proc を適用する方針が選択されました。PR 本文に記載された通り、ユーザーが追加したカスタム Proc は self 参照の有無を判定できないため、デフォルトフィルタ・サイレンサーだけを安全に共有可能にすることで既存の動作を保ちつつ Ractor 互換性を確保しています。クラス側で instance_exec を使用するマクロ系のブロックは別途対応が検討されていますが、今回の変更は後方互換性と安全性を最優先した実装です。

まとめ

この PR により、Rails のバックトレースクリーンナーはデフォルトで Ractor 共有可能となり、Rails.application 全体を Ractor に渡す際の障壁が除去されました。既存のフィルタ・サイレンサーの動作は変わらず、追加されたテストで共有可能性が保証されているため、開発者は設定変更なしで安全に Ractor 化を利用できます。

記事メタデータ

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

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

品質レビュー結果

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

Review Criteria:

記事構成 ✓ PASS

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

リード文がタイトル直下に配置され、背景・技術的変更・設計判断・まとめの各セクションが揃っており、結論はリード文の単なる繰り返しではなく意義を付加しています。

カスタムMarkdown構文 ✓ PASS

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

ファイル名付きシンタックスハイライトは ```ruby:パス の形式で正しく記述され、PRリンクも [#57574](URL) の形で正規化されています。

対象読者への適合性 ✓ PASS

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

内容は Rails エンジニア向けで、専門用語が適切に使われており、初心者向けの余計な説明はありません。

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

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

各セクションは「総論→各論→結論」の構成になり、段落はトピックセンテンスで始まり1トピックに絞られ、長すぎる段落や空行の欠如は見られません。

Diff内容との照合 ✓ PASS

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

記事中のコードブロックは提供された Diff と内容的に一致しており、ファイル名・変更箇所・追加コードが正確に反映されています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

Ractor、shareable_proc、BacktraceCleaner などの用語は PR と一致し、誤用はありません。

説明の技術的正確性 ✓ PASS

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

技術的な説明は Diff と PR の記述に基づき正確で、因果関係も妥当です。

事実の突合 ✓ PASS

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

記事のすべての主張は PR のタイトル、説明、Diff、テスト追加に裏付けられ、憶測や根拠のない情報は含まれていません。

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

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

PR 番号 #57574 だけが記載されており、正確です。その他数値情報はありません。

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

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

日本語タイトルは PR の意味「Make the backtrace cleaner ractor shareable by default」を正しく訳しています。

外部知識の正確性 ✓ PASS

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

Rails のバージョンサポート状況やベンチマーク等、PR に記載のない外部知識は一切含まれていません。

時間表現の正確性 ✓ PASS

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

時間表現は使用されておらず、PR の表現と齟齬はありません。