aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2006-11-11 08:08:53 +0000
committerJeremy Kemper <jeremy@bitsweat.net>2006-11-11 08:08:53 +0000
commit2a92995d2ab33c630271746b7ec172bcd07daddf (patch)
treeca0d61f7eadaa45a225ee4e8cf778fb60e511404 /railties/lib
parent2e0b33f27781826ef399110701f3da541d36eca3 (diff)
downloadrails-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.rb36
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