Spring の Unreleased CHANGELOG に `after_environment_load` フックほか3件の変更が追加
Spring の次期リリースに向けた CHANGELOG に、Spring.after_environment_load フックの追加、クライアント切断時のクラッシュ修正、フレームワーク基底クラスの先行オートロードという3件の変更がまとめられました。
背景
Spring はテスト実行を高速化するためにアプリケーション環境をプリロードし、フォークしたワーカープロセスへ copy-on-write で共有する設計を持ちます。今回の CHANGELOG 更新は、この設計をさらに活用するための拡張と、既存の安定性問題の修正を記録しています。
変更は3件で構成されており、1件は新機能、2件は既存の不具合修正です。これらはいずれも Spring サーバープロセスのライフサイクル管理に関わる変更です。
技術的な変更
Spring.after_environment_load フックの追加
新たに Spring.after_environment_load フックが追加され、Rails アプリケーション環境のロード直後・GC.compact / Process.warmup 実行前・サーバーの待機ループ開始前というタイミングで任意のコードを実行できるようになりました。
このフックの主な用途は、テスト基盤の事前ロードです。テストヘルパー、フィクスチャキャッシュ、データストア接続といった高コストな初期化処理を Spring サーバープロセス側で済ませておくことで、フォークした各テストワーカーが copy-on-write によってその成果を継承できます。これにより、従来は各ワーカー起動のたびに発生していた初期化コストを削減できます。
クライアント切断時のクラッシュ修正
Errno::EPIPE がアクセプトループまで伝播して Spring プロセス自体を終了させてしまう問題が修正されました。具体的には、Spring::Server#serve および Spring::Application#serve の両クラッシュポイントで例外が補足されるようになっています。
修正前は、クライアントが接続タイムアウト等でハンドシェイク途中に切断した場合、Errno::EPIPE が捕捉されずにプロセスを終了させ、残留したソケットがその後のすべてのクライアント接続を破壊していました。さらに、Application#serve 内の rescue Exception ハンドラがエラー報告のための書き込みを行う際にも同様のクラッシュが発生し得ましたが、このケースも合わせて修正されています。
フレームワーク基底クラスの先行オートロード
プリロード完了時に ActionMailer::Base、ActionController::Base、ActionController::API を先行してオートロードすることで、ActiveSupport.on_load フックが親プロセス内で確実に発火するようになりました。
この修正がなかった場合、#serve 内のリローダープローブが Rails 内部(特に Action View の CacheExpiry::ViewReloader)を半初期化状態でマテリアライズし、各フォーク内の prepend_view_path 呼び出しのたびに高コストな FileUpdateChecker の再構築を引き起こしていました。この変更は rails/rails#51308 で定義された遅延初期化の契約に沿うものです。
設計判断
after_environment_load フックの設計において、実行タイミングが GC.compact / Process.warmup の前に設定されている点が重要です。フック内でロードしたオブジェクトのメモリレイアウトが、その後のメモリ最適化処理の対象に含まれることを意図した配置といえます。
フレームワーク基底クラスの先行オートロードは、「親プロセスで完全に初期化されたオブジェクトだけをフォーク前に持つ」という Spring の copy-on-write 戦略を徹底する方針の表れです。半初期化状態のオブジェクトをフォーク後に完成させようとすると、各ワーカーで独立したページフォルトと再初期化が発生するという問題を、親プロセス側での先行ロードで根本的に回避しています。
まとめ
今回の CHANGELOG 更新は、Spring のプリフォーク型アーキテクチャを最大限に活用するための機能拡張と安定性改善を記録しています。after_environment_load フックによってアプリケーション側からのカスタム事前ロードが可能になり、フレームワーク基底クラスの先行初期化とクラッシュ修正が組み合わさることで、Spring サーバーの信頼性と各ワーカーの起動効率が向上します。