&tag(Rails3/起動時の流れ); *目次 [#dba70d82] #contents *参考情報 [#e9eb92bf] *前提 [#f0eafa32] -Railsアプリを起動した時の処理の流れ。以下のコマンドで起動したときどういう風にWEBrickが起動されるか。 scrpt/rails server *script/rails [#rc490313] -アプリディレクトリのscript/railsがエントリーポイント。 #pre{{ APP_PATH = File.expand_path('../../config/application', __FILE__) require File.expand_path('../../config/boot', __FILE__) require 'rails/commands' }} *railties [#p9b0ae66] **rails/commands.rb [#p4645653] -ここでコマンドラインオプションが処理される。引数がserverの場合次の処理が実行される。 #pre{{ when 'server' # Change to the application's path if there is no config.ru file in current dir. # This allows us to run script/rails server from other directories, but still get # the main config.ru and properly set the tmp directory. Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru")) require 'rails/commands/server' Rails::Server.new.tap { |server| # We need to require application after the server sets environment, # otherwise the --environment option given to the server won't propagate. require APP_PATH Dir.chdir(Rails.application.root) server.start } }} ** rails/commands/server.rb [#e1066b72] -Rails::Serverは、Rack::Serverのサブクラスであることが分かる #pre{{ module Rails class Server < ::Rack::Server }} *rack [#oe1d667c] ** rack/server.rb [#v4aa2b01] -Rack::Serverが実際にどのサーバーを使うかは以下の処理で決定されている。 #pre{{ def server @_server ||= Rack::Handler.get(options[:server]) || Rack::Handler.default(options) end }} -options[:server]に使用するサーバーが設定されていない場合、Rack::Handler.default(options)によって決まる。 **rack/handler.rb [#t64bbdcb] -使用するデフォルトのサーバーを決定する処理。 Rack::Handler::Thinがエラーになれば、Rack::Handler::WEBrickが使われることが分かる。 #pre{{ def self.default(options = {}) # Guess. if ENV.include?("PHP_FCGI_CHILDREN") # We already speak FastCGI options.delete :File options.delete :Port Rack::Handler::FastCGI elsif ENV.include?("REQUEST_METHOD") Rack::Handler::CGI else begin Rack::Handler::Thin rescue LoadError Rack::Handler::WEBrick end end end }} *ログ出力の改善 [#gb489538] **WEBrickのログ出力機能に関して [#xf3ebdc1] -WEBrickは、development.logにログを出力すると同時に標準出力にもログを表示している。 -この仕組は、railtiesのrails/rack/log_trailer.rbで行われているようだ。 #pre{{ def tail! return unless @cursor @file.seek @cursor unless @file.eof? contents = @file.read @cursor = @file.tell $stdout.print contents end end }} -ログファイルをシークしながら標準出力に差分を表示していることがわかる。 **Could not determine content-length of response body. Set content-length of the response or set Response#chunked = trueがうざい。 [#pddfa72e] -[[Could not determine content-length of response body. Set content-length of the response or set Response#chunked = trueとassetのログがウザい件 - リア充爆発日記:http://d.hatena.ne.jp/ria10/20120209/1328757610]]が参考になる。 -[[204_304_keep_alive.patch - ruby-trunk - Ruby Issue Tracking System:https://bugs.ruby-lang.org/attachments/2300/204_304_keep_alive.patch]]のパッチを適用する。lib/webrick/httpresponse.rbを修正する。以下の4行目のところ。 -[[204_304_keep_alive.patch - ruby-trunk - Ruby Issue Tracking System:https://bugs.ruby-lang.org/attachments/2300/204_304_keep_alive.patch]]のパッチを適用する。 #pre{{ $ emacs -nw versions/1.9.3-p429/lib/ruby/1.9.1/webrick/httpresponse.rb }} -以下の4行目のところ。 #pre{{ if @header['connection'] == "close" @keep_alive = false elsif keep_alive? if chunked? || @header['content-length'] || @status == 304 || @status == 204 @header['connection'] = "Keep-Alive" else msg = "Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true" }}