diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2005-09-28 08:38:26 +0000 |
---|---|---|
committer | David Heinemeier Hansson <david@loudthinking.com> | 2005-09-28 08:38:26 +0000 |
commit | b7faeb20e96eceafaf7fdc9c3545afbbaaf283c7 (patch) | |
tree | b4ad0132c0c45f9e488795585a6537c2b02e3562 | |
parent | 5d19fd784127f3e3ae0be94d718b89c255edf065 (diff) | |
download | rails-b7faeb20e96eceafaf7fdc9c3545afbbaaf283c7.tar.gz rails-b7faeb20e96eceafaf7fdc9c3545afbbaaf283c7.tar.bz2 rails-b7faeb20e96eceafaf7fdc9c3545afbbaaf283c7.zip |
Added in-process restarting on USR2 -- still missing a good way to free up the socket, so not a complete solution yet.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2390 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rw-r--r-- | railties/lib/fcgi_handler.rb | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/railties/lib/fcgi_handler.rb b/railties/lib/fcgi_handler.rb index 1e3061fe49..ecffec9aa6 100644 --- a/railties/lib/fcgi_handler.rb +++ b/railties/lib/fcgi_handler.rb @@ -1,12 +1,14 @@ require 'fcgi' require 'logger' require 'dispatcher' +require 'rbconfig' class RailsFCGIHandler SIGNALS = { 'HUP' => :reload, 'TERM' => :graceful_exit, - 'USR1' => :graceful_exit + 'USR1' => :graceful_exit, + 'USR2' => :graceful_restart } attr_reader :when_ready @@ -40,7 +42,7 @@ class RailsFCGIHandler # Start error timestamp at 11 seconds ago. @last_error_on = Time.now - 11 - dispatcher_log(:info, "starting") + dispatcher_log :info, "starting" end def process!(provider = FCGI) @@ -61,8 +63,8 @@ class RailsFCGIHandler process_request(cgi) - # Break if graceful exit requested. - break if when_ready == :exit + # Break if graceful exit or restart requested. + break if when_ready == :exit || when_ready == :restart # Garbage collection countdown. if gc_request_period @@ -71,11 +73,16 @@ class RailsFCGIHandler end end + if when_ready == :restart + dispatcher_log :info, "restarted gracefully" + restart! + end + GC.enable - dispatcher_log(:info, "terminated gracefully") + dispatcher_log :info, "terminated gracefully" rescue SystemExit => exit_error - dispatcher_log(:info, "terminated by explicit exit") + dispatcher_log :info, "terminated by explicit exit" rescue Object => fcgi_error # retry on errors that would otherwise have terminated the FCGI process, @@ -103,7 +110,7 @@ class RailsFCGIHandler STDERR << " #{log_error.class}: #{log_error.message}\n" end - def dispatcher_error(e,msg="") + def dispatcher_error(e, msg = "") error_message = "Dispatcher failed to catch: #{e} (#{e.class})\n" + " #{e.backtrace.join("\n ")}\n#{msg}" @@ -112,12 +119,12 @@ class RailsFCGIHandler def install_signal_handlers SIGNALS.each do |signal, handler_name| - install_signal_handler signal, method("#{handler_name}_handler").to_proc + install_signal_handler(signal, method("#{handler_name}_handler").to_proc) end end def install_signal_handler(signal, handler) - trap signal, handler + trap(signal, handler) rescue ArgumentError dispatcher_log :warn, "Ignoring unsupported signal #{signal}." end @@ -128,8 +135,13 @@ class RailsFCGIHandler end def reload_handler(signal) - @when_ready = :reload dispatcher_log :info, "asked to reload ASAP" + @when_ready = :reload + end + + def graceful_restart_handler(signal) + dispatcher_log :info, "asked to restart ASAP" + @when_ready = :restart end def process_request(cgi) @@ -149,6 +161,16 @@ class RailsFCGIHandler ActionController::Routing::Routes.reload end + def restart! + config = ::Config::CONFIG + ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT'] + command_line = [ruby, $0, ARGV].flatten.join(' ') + + dispatcher_log :info, "restarted" + + exec(command_line) + end + def run_gc! @gc_request_countdown = gc_request_period GC.enable; GC.start; GC.disable |