Spring の動作
- Spring サーバーが起動する。
- サーバーが起動したクライアントを受け付ける。
- サーバーがクライアントからコマンドを受け取る。
(rails_console
/rails_runner
/rake
など) - アプリケーションマネージャーに問い合わせる。
- 環境毎の子プロセスが起動していなかったらプロセスを生成する。(
Process.spawn
) - アプリケーションプロセス (子プロセス) がクライアントと接続する。
- アプリケーションプロセスにアプリケーションをプリロードする。
(初回及び更新時のみ) - ウォッチャーに監視するファイルを追加する。
- ワーカープロセスをフォークする。
- アプリケーションマネージャーにワーカーの PID が返される。
- サーバーが実行しているメインスレッドでワーカーの終了を待つ。
(複数コマンドが並列に実行される。)
クライアントにおけるコマンドの実行
- サーバーと接続する UNIX ソケットをオープンする。
- 接続できなかった場合はコールドラン、接続できた場合はウォームランで開始する。
- コールドランではサーバーを起動できたら、接続してコマンドを実行する。
- ウォームランではそのままコマンドの実行に移る。
- アプリケーションとクライアントを接続する UNIX ソケットのペアを作成する。
- シグナル用のキューを用意する。
- サーバーにコマンド、引数、及び環境変数を JSON 形式で送信する。
- アプリケーションプロセスと接続し、コマンドを送信して実行を開始する。
- アプリケーションに IO を接続する。
- アプリケーションにコマンド、引数、及び環境変数を JSON 形式で送信する。
- サーバーからワーカーの PID が返される。
- サーバーと接続しているソケットを閉じる。
(アプリケーションとダイレクトに接続しているのでサーバーとの通信は不要となる。) - シグナルキューにシグナルがあれば、アプリケーションにシグナルを送信する。
- 以後はシグナルキューを使わずに、すぐにアプリケーションにシグナルを転送する。
- アプリケーションから終了コードが送られてくる。
- 受け取った終了コードでクライアントを終了する。
failsafe_thread
例外が発生しても外側に伝播しないようにスレッドで処理を実行する。
def failsafe_thread Thread.new { begin yield rescue end } end
参考:
spring/failsafe_thread.rb at v2.0.2 · rails/spring – GitHub
rails/spring の役割
参考:
rails/spring コードリーディング | freedom-man
コマンドの実行
コマンド実行時の処理
lib/binstub
bin/spring
Client.run(ARGV)
rails
コマンド ( console
/ runner
/ generate
/ destroy
/ test
) の場合
Client::Rails.call(args)
Client::Run.call(["rails_#{command_name}", *args.drop(2)])
rake
コマンドの場合
Client::Run.call(args)
参考:
spring/binstub.rb at v2.0.2 · rails/spring – GitHub
spring/spring at v2.0.2 · rails/spring – GitHub
spring/client.rb at v2.0.2 · rails/spring – GitHub
spring/rails.rb at v2.0.2 · rails/spring – GitHub
spring/run.rb at v2.0.2 · rails/spring – GitHub
spring/command.rb at v2.0.2 · rails/spring – GitHub
プロセスの生成
- アプリケーションサーバー
- Spring サーバー
参考:
start_child – spring/application_manager.rb at v2.1.0 · rails/spring – GitHub
boot_server – spring/run.rb at v2.1.0 · rails/spring – GitHub
start_watcher
ファイルの監視を開始する。
参考:
start_watcher – spring/application.rb at v2.1.0 · rails/spring – GitHub
run
アプリケーションサーバーの実行を開始して、クライアントからの接続を待ち受ける。
参考:
run – spring/application.rb at v2.1.0 · rails/spring – GitHub
preload
アプリケーションの起動を高速化するために、予めメモリ上にロードしておく。
参考:
preload – spring/application.rb at v2.1.0 · rails/spring – GitHub
eager_preload
アプリケーションサーバーの開始前に、明示的にアプリケーションをプリロードする。
参考:
eager_preload – spring/application.rb at v2.1.0 · rails/spring – GitHub
eager_preload – spring/boot.rb at v2.1.0 · rails/spring – GitHub
ソース
Spring.register_command / Spring.command
処理可能なコマンドの名前とオブジェクトを登録し、クライアントから Spring サーバーに送られてきたコマンドに対して応答するコマンドのオブジェクトを返す。
参考:
spring/commands.rb at v2.1.0 · rails/spring – GitHub
Spring::Commands::Rails
rails
コマンドを処理するクラス群の基本クラス
派生クラス
参考:
spring/rails.rb at v2.1.0 · rails/spring – GitHub
Spring::Commands::Rake
rake
コマンドを処理するクラス
参考:
spring/rake.rb at v2.1.0 · rails/spring – GitHub
Spring::CommandWrapper
コマンドのラッパー
参考:
spring/command_wrapper.rb at v2.1.0 · rails/spring – GitHub
Spring::Env
アプリケーションの実行環境を保持するクラス
参考:
spring/env.rb at v2.1.0 · rails/spring – GitHub
Spring::Client::Command
クライアントで実行されるコマンドの引数と環境を保持するクラス
参考:
spring/command.rb at v2.1.0 · rails/spring – GitHub
Spring::Client::Rails
クライアントで rails
コマンドを実行するクラス
参考:
spring/rails.rb at v2.1.0 · rails/spring – GitHub
Spring::Client::Run
クライアントでコマンドの実行を司るクラス
参考:
spring/run.rb at v2.1.0 · rails/spring – GitHub
Spring::Server
Spring サーバーの起動と停止、クライアントの接続を管理する。
参考:
spring/server.rb at v2.1.0 · rails/spring – GitHub
Spring::ApplicationManager
Spring サーバーでアプリケーションを実行するプロセスを生成して管理する。
参考:
spring/application_manager.rb at v2.1.0 · rails/spring – GitHub
Spring::Application
Rails アプリケーションをプリロードし、プロセスをフォークしてクライアントから受信したコマンドを実行する。
参考: