[Rails] Console `reload!` コマンドがExecutorをリセットするように改善

rails/rails

背景

Rails 8.0では#56297でコンソールがExecutorでラップされるようになりました。これにより、Query Cacheが暗黙的に有効化されるなどの副作用が発生していました(#56473で報告)。

コンソールセッションは通常、長時間再利用されるため、Executorのライフサイクルを適切に管理する仕組みが必要でした。本PRでは、reload! コマンド実行時にExecutorもリセットされるように改善されました。

技術的な変更内容

ActiveSupport::Executorに reset オプションを追加

ActiveSupport::Executor#run! メソッドに reset オプションが追加されました。このオプションを true にすると、現在のExecutorコンテキストを一度完了させ、新しいコンテキストを開始します。

def test_run_with_reset_invokes_callbacks_within_wrap
  called = []
  executor.to_run { called << :run }
  executor.to_complete { called << :complete }
  executor.wrap do
    called << :before_reset
    executor.run!(reset: true)
    called << :after_reset
  end
  assert_equal [:run, :before_reset, :complete, :run, :after_reset, :complete], called
end

このテストからわかるように、reset: true を指定すると以下の動作が行われます:

  1. 現在のExecutorコンテキストの complete コールバックが実行される
  2. 新しいExecutorコンテキストの run コールバックが実行される
  3. 外側の wrap ブロック終了時に再度 complete コールバックが実行される

Console reload! コマンドの拡張

コンソールの reload! コマンドが、Executorがアクティブな場合にリセットを実行するように変更されました。

def execute
  puts "Reloading..."
  executor = Rails.application.executor
  executor.run!(reset: true) if executor.active?
  Rails.application.reloader.reload!
end

重要なポイント:

  • Executorがアクティブな場合のみリセットを実行(if executor.active?
  • コードのリロード(Rails.application.reloader.reload!)の前にExecutorをリセット
  • --skip-executor オプション付きで起動した場合は、Executorのリセットはスキップされる

テストケースの追加

2つのテストケースが追加され、動作が保証されています:

def test_reload_command_resets_executor
  spawn_console("-e development")

  write_prompt "key = Rails.application.executor.active_key; nil"
  write_prompt "old_executor_id = ActiveSupport::IsolatedExecutionState[key].object_id; nil"
  write_prompt "reload!", "Reloading...\r\n"
  write_prompt "ActiveSupport::IsolatedExecutionState[key].object_id != old_executor_id", "=> true"
end

このテストは、reload! 実行後にExecutorの内部状態(IsolatedExecutionState)が新しいオブジェクトに置き換わることを検証しています。

def test_reload_command_does_not_start_executor_when_it_is_not_active
  spawn_console("-e development --skip-executor")

  write_prompt "Rails.application.executor.active?", "=> false"
  write_prompt "reload!", "Reloading...\r\n"
  write_prompt "Rails.application.executor.active?", "=> false"
end

このテストは、--skip-executor オプション使用時に reload! がExecutorを起動しないことを確認しています。

実用的な影響

この変更により、以下のようなケースでコンソールの動作がより予測可能になります:

  • Query Cacheが有効な状態で長時間作業した後、reload! でキャッシュ状態をクリアできる
  • Executorのコールバック(例:ログ出力やメトリクス収集)が適切にリセットされる
  • コンソールセッションを再起動せずに、クリーンな状態から作業を再開できる

従来は、これらの状態をリセットするにはコンソールを再起動する必要がありましたが、本変更により reload! コマンドだけで対応可能になりました。

記事メタデータ

Generated by:
Claude Sonnet 4.5 for DiffDaily

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

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

ガイドライン準拠 ✓ PASS

記事構成とDiffDaily Styleへの準拠状況

記事構成、カスタムMarkdown構文、対象読者への適合性の全項目でガイドラインを完全に遵守しています。特に、必須3要素(Title, Context, Technical Detail)が明確に分離され、コードブロックの書式も完璧で、非常に読みやすい記事になっています。

  • 記事構成(Title、Context、Technical Detail)
  • DiffDaily Styleガイド準拠
  • カスタムMarkdown活用
  • 対象読者への適合性
技術的整合性 ✓ PASS

技術的な正確性と表現の適切性

記事内で引用されているコードはPRの核心的な変更点を的確に示しており、技術的な解説も正確です。特に、テストコードを根拠に`reset: true`オプションの挙動を説明する手法は、変更内容の理解を深めるのに非常に効果的です。

  • 技術用語の正確性
  • コード例の正確性
  • 説明の技術的正確性
PR内容との整合性 ✓ PASS

元のPR情報との一致度

PRのタイトルや目的に忠実な内容であり、ハルシネーションは一切見られません。背景情報として関連するPRやIssueへの言及も正確で、変更の文脈を読者に正しく伝えています。数値や固有名詞もすべて正確です。

  • タイトル・説明の一致
  • Diff内容の正確な反映
  • 推測の排除