Spring の動作

  1. Spring サーバーが起動する。
  2. サーバーが起動したクライアントを受け付ける。
  3. サーバーがクライアントからコマンドを受け取る。
    (rails_console / rails_runner / rake など)
  4. アプリケーションマネージャーに問い合わせる。
  5. 環境毎の子プロセスが起動していなかったらプロセスを生成する。(Process.spawn)
  6. アプリケーションプロセス (子プロセス) がクライアントと接続する。
  7. アプリケーションプロセスにアプリケーションをプリロードする。
    (初回及び更新時のみ)
  8. ウォッチャーに監視するファイルを追加する。
  9. ワーカープロセスをフォークする。
  10. アプリケーションマネージャーにワーカーの PID が返される。
  11. サーバーが実行しているメインスレッドでワーカーの終了を待つ。
    (複数コマンドが並列に実行される。)

クライアントにおけるコマンドの実行

  1. サーバーと接続する UNIX ソケットをオープンする。
  2. 接続できなかった場合はコールドラン、接続できた場合はウォームランで開始する。
  3. コールドランではサーバーを起動できたら、接続してコマンドを実行する。
  4. ウォームランではそのままコマンドの実行に移る。
  5. アプリケーションとクライアントを接続する UNIX ソケットのペアを作成する。
  6. シグナル用のキューを用意する。
  7. サーバーにコマンド、引数、及び環境変数を JSON 形式で送信する。
  8. アプリケーションプロセスと接続し、コマンドを送信して実行を開始する。
  9. アプリケーションに IO を接続する。
  10. アプリケーションにコマンド、引数、及び環境変数を JSON 形式で送信する。
  11. サーバーからワーカーの PID が返される。
  12. サーバーと接続しているソケットを閉じる。
    (アプリケーションとダイレクトに接続しているのでサーバーとの通信は不要となる。)
  13. シグナルキューにシグナルがあれば、アプリケーションにシグナルを送信する。
  14. 以後はシグナルキューを使わずに、すぐにアプリケーションにシグナルを転送する。
  15. アプリケーションから終了コードが送られてくる。
  16. 受け取った終了コードでクライアントを終了する。

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

コマンドの実行

コマンド実行時の処理

  1. lib/binstub
  2. bin/spring
  3. Client.run(ARGV)

rails コマンド ( console / runnergenerate / destroy / test ) の場合

  1. Client::Rails.call(args)
  2. Client::Run.call(["rails_#{command_name}", *args.drop(2)])

rake コマンドの場合

  1. 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 アプリケーションをプリロードし、プロセスをフォークしてクライアントから受信したコマンドを実行する。

参考:

spring/application.rb at v2.1.0 · rails/spring – GitHub

タグ:

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です