Action CableとAction Dispatchのロードフック保護を解除
この変更により、action_dispatch_requestとaction_cableのロードフック保護が解除されました。これらのコンポーネントは本番環境のアプリケーション初期化時に常にロードされるため、起動後の遅延ロードを前提とした保護が実質的に機能していませんでした。
背景
#56201で導入されたロードフック保護機能は、Railsアプリケーションの初期化前にコンポーネントがロードされることによるバグやパフォーマンス劣化を防ぐ仕組みでした。この機能はguard_load_hooksメソッドを通じて、ロードフックが早すぎるタイミングで実行された場合に警告またはエラーを発生させます。
保護機能の前提は「該当コンポーネントがリクエスト時に初めてロードされる」ことでした。しかし、ActionDispatch::RequestとActionCable::Serverは本番環境でアプリケーション起動時に必ずロードされるため、この前提が成立していませんでした。実際には起動完了前にロードされるコンポーネントに対して「起動後のロード」を期待する保護をかけていたことになります。
技術的な変更
actionpack/lib/action_dispatch/railtie.rbとactioncable/lib/action_cable/engine.rbのguard_load_hooks呼び出しから、該当するロードフックが削除されました。
Action Dispatchの変更:
guard_load_hooks(
:action_dispatch_response, :action_dispatch_system_test_case,
:action_dispatch_integration_test,
)
:action_dispatch_requestが保護対象から除外されています。:action_dispatch_responseや:action_dispatch_integration_testは引き続き保護されており、これらはテスト実行時やリクエスト処理時に初めてロードされる可能性があるためです。
Action Cableの変更:
guard_load_hooks(
:action_cable_channel, :action_cable_connection,
:action_cable_test_case, :action_cable_connection_test_case,
)
:action_cableが保護対象から除外されました。チャネルやコネクション関連のロードフックは引き続き保護されており、WebSocket接続時に初めてロードされる可能性があるためです。
さらに、Action Cableではチャネルコールバックの設定場所も変更されています:
ActiveSup port.on_load(:action_cable_channel) do
wrap = lambda do |_, inner|
app.executor.wrap(source: "application.action_cable", &inner)
end
ActionCable::Channel::Base.set_callback :subscribe, :around, prepend: true, &wrap
ActionCable::Channel::Base.set_callback :unsubscribe, :around, prepend: true, &wrap
end
以前は:action_cableロードフック内でチャネルコールバックを設定していましたが、これはActionCable.serverの初期化時にすべてのチャネルクラスをロードする副作用を引き起こしていました。:action_cable_channelロードフック内に移動することで、チャネルクラスが実際に使用されるタイミングまでコールバック設定を遅延させています。
設計判断
現実のロード動作に合わせた保護対象の見直しが行われました。
ロードフック保護機能の目的は、想定外のタイミングでのコンポーネントロードを検出することです。しかし、実装上常に起動時にロードされるコンポーネントに対して保護をかけることは、誤検出を生むだけで実質的な保護効果がありません。PR内では「we can't guarantee requests will load after boot」と述べられており、本番環境での実際の動作を尊重した判断です。
一方で、:action_cable_channelや:action_dispatch_responseのような、リクエスト処理やWebSocket接続時に初めてロードされる可能性があるコンポーネントは引き続き保護されています。これにより、保護機能が本来の目的である「遅延ロード可能なコンポーネントの早期ロード検出」に集中できるようになりました。
チャネルコールバックの移動は、サーバー初期化とチャネルロードのタイミングを分離する副次的な改善です。これにより、Action Cableサーバーの起動がチャネルクラスのロードに依存しなくなり、起動処理がより軽量化されます。
本PRは、理想と現実のギャップを認識し、保護機能の適用範囲を実際のロード動作に合わせて調整した変更です。すべてのロードフックを一律に保護するのではなく、実際に遅延ロード可能なコンポーネントに絞り込むことで、保護機能の有効性を高めています。