aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2005-09-28 08:38:26 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2005-09-28 08:38:26 +0000
commitb7faeb20e96eceafaf7fdc9c3545afbbaaf283c7 (patch)
treeb4ad0132c0c45f9e488795585a6537c2b02e3562
parent5d19fd784127f3e3ae0be94d718b89c255edf065 (diff)
downloadrails-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.rb42
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