diff options
author | Jeremy Kemper <jeremy@bitsweat.net> | 2006-11-11 08:08:53 +0000 |
---|---|---|
committer | Jeremy Kemper <jeremy@bitsweat.net> | 2006-11-11 08:08:53 +0000 |
commit | 2a92995d2ab33c630271746b7ec172bcd07daddf (patch) | |
tree | ca0d61f7eadaa45a225ee4e8cf778fb60e511404 /railties/lib | |
parent | 2e0b33f27781826ef399110701f3da541d36eca3 (diff) | |
download | rails-2a92995d2ab33c630271746b7ec172bcd07daddf.tar.gz rails-2a92995d2ab33c630271746b7ec172bcd07daddf.tar.bz2 rails-2a92995d2ab33c630271746b7ec172bcd07daddf.zip |
Only wrap request processing with our USR1 signal handler so FastCGI can trap it and raise an exception while waiting for connections. Idle processes exit immediately rather than waiting for another request; active processes gracefully exit when the request is finished.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@5485 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'railties/lib')
-rw-r--r-- | railties/lib/fcgi_handler.rb | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/railties/lib/fcgi_handler.rb b/railties/lib/fcgi_handler.rb index 80ce1a34f5..d7e95b8fbe 100644 --- a/railties/lib/fcgi_handler.rb +++ b/railties/lib/fcgi_handler.rb @@ -6,11 +6,13 @@ require 'rbconfig' class RailsFCGIHandler SIGNALS = { 'HUP' => :reload, + 'INT' => :exit_now, 'TERM' => :exit_now, 'USR1' => :exit, 'USR2' => :restart, 'SIGTRAP' => :breakpoint } + GLOBAL_SIGNALS = SIGNALS.keys - %w(USR1) attr_reader :when_ready @@ -92,17 +94,23 @@ class RailsFCGIHandler end def install_signal_handlers - SIGNALS.each do |signal, handler_name| - install_signal_handler(signal, method("#{handler_name}_handler").to_proc) - end + GLOBAL_SIGNALS.each { |signal| install_signal_handler(signal) } end - def install_signal_handler(signal, handler) + def install_signal_handler(signal, handler = nil) + handler ||= method("#{SIGNALS[signal]}_handler").to_proc trap(signal, handler) rescue ArgumentError dispatcher_log :warn, "Ignoring unsupported signal #{signal}." end + def with_signal_handler(signal) + install_signal_handler(signal) + yield + ensure + install_signal_handler(signal, 'DEFAULT') + end + def exit_now_handler(signal) dispatcher_log :info, "asked to terminate immediately" exit @@ -127,10 +135,13 @@ class RailsFCGIHandler dispatcher_log :info, "asked to breakpoint ASAP" @when_ready = :breakpoint end - + def process_each_request!(provider) - provider.each_cgi do |cgi| - process_request(cgi) + cgi = nil + provider.each_cgi do |cgi| + with_signal_handler 'USR1' do + process_request(cgi) + end case when_ready when :reload @@ -148,6 +159,9 @@ class RailsFCGIHandler gc_countdown end + rescue SignalException => signal + raise unless signal.message == 'SIGUSR1' + close_connection(cgi) if cgi end def process_request(cgi) @@ -161,7 +175,7 @@ class RailsFCGIHandler 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) @@ -183,7 +197,7 @@ class RailsFCGIHandler Dispatcher.reset_application! ActionController::Routing::Routes.reload end - + def breakpoint! require 'breakpoint' port = defined?(BREAKPOINT_SERVER_PORT) ? BREAKPOINT_SERVER_PORT : 42531 @@ -197,14 +211,14 @@ class RailsFCGIHandler @gc_request_countdown = gc_request_period GC.enable; GC.start; GC.disable end - + def gc_countdown if gc_request_period @gc_request_countdown -= 1 run_gc! if @gc_request_countdown <= 0 end end - + def close_connection(cgi) cgi.instance_variable_get("@request").finish end |