提交 2a92995d 编写于 作者: J Jeremy Kemper

Only wrap request processing with our USR1 signal handler so FastCGI can trap...

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
上级 2e0b33f2
*SVN* *SVN*
* 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. [Jeremy Kemper]
* Alter prior change to use require_dependency instead of require_or_load. Causes ApplicationController to be reloaded again. Closes #6587. [Nicholas Seckar] * Alter prior change to use require_dependency instead of require_or_load. Causes ApplicationController to be reloaded again. Closes #6587. [Nicholas Seckar]
* Rake: use absolute paths to load lib and vendor tasks so they may be run outside of RAILS_ROOT. #6584 [jchris] * Rake: use absolute paths to load lib and vendor tasks so they may be run outside of RAILS_ROOT. #6584 [jchris]
......
...@@ -6,11 +6,13 @@ ...@@ -6,11 +6,13 @@
class RailsFCGIHandler class RailsFCGIHandler
SIGNALS = { SIGNALS = {
'HUP' => :reload, 'HUP' => :reload,
'INT' => :exit_now,
'TERM' => :exit_now, 'TERM' => :exit_now,
'USR1' => :exit, 'USR1' => :exit,
'USR2' => :restart, 'USR2' => :restart,
'SIGTRAP' => :breakpoint 'SIGTRAP' => :breakpoint
} }
GLOBAL_SIGNALS = SIGNALS.keys - %w(USR1)
attr_reader :when_ready attr_reader :when_ready
...@@ -92,17 +94,23 @@ def dispatcher_error(e, msg = "") ...@@ -92,17 +94,23 @@ def dispatcher_error(e, msg = "")
end end
def install_signal_handlers def install_signal_handlers
SIGNALS.each do |signal, handler_name| GLOBAL_SIGNALS.each { |signal| install_signal_handler(signal) }
install_signal_handler(signal, method("#{handler_name}_handler").to_proc)
end
end end
def install_signal_handler(signal, handler) def install_signal_handler(signal, handler = nil)
handler ||= method("#{SIGNALS[signal]}_handler").to_proc
trap(signal, handler) trap(signal, handler)
rescue ArgumentError rescue ArgumentError
dispatcher_log :warn, "Ignoring unsupported signal #{signal}." dispatcher_log :warn, "Ignoring unsupported signal #{signal}."
end end
def with_signal_handler(signal)
install_signal_handler(signal)
yield
ensure
install_signal_handler(signal, 'DEFAULT')
end
def exit_now_handler(signal) def exit_now_handler(signal)
dispatcher_log :info, "asked to terminate immediately" dispatcher_log :info, "asked to terminate immediately"
exit exit
...@@ -127,10 +135,13 @@ def breakpoint_handler(signal) ...@@ -127,10 +135,13 @@ def breakpoint_handler(signal)
dispatcher_log :info, "asked to breakpoint ASAP" dispatcher_log :info, "asked to breakpoint ASAP"
@when_ready = :breakpoint @when_ready = :breakpoint
end end
def process_each_request!(provider) def process_each_request!(provider)
provider.each_cgi do |cgi| cgi = nil
process_request(cgi) provider.each_cgi do |cgi|
with_signal_handler 'USR1' do
process_request(cgi)
end
case when_ready case when_ready
when :reload when :reload
...@@ -148,6 +159,9 @@ def process_each_request!(provider) ...@@ -148,6 +159,9 @@ def process_each_request!(provider)
gc_countdown gc_countdown
end end
rescue SignalException => signal
raise unless signal.message == 'SIGUSR1'
close_connection(cgi) if cgi
end end
def process_request(cgi) def process_request(cgi)
...@@ -161,7 +175,7 @@ def restart! ...@@ -161,7 +175,7 @@ def restart!
config = ::Config::CONFIG config = ::Config::CONFIG
ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT'] ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT']
command_line = [ruby, $0, ARGV].flatten.join(' ') command_line = [ruby, $0, ARGV].flatten.join(' ')
dispatcher_log :info, "restarted" dispatcher_log :info, "restarted"
exec(command_line) exec(command_line)
...@@ -183,7 +197,7 @@ def restore! ...@@ -183,7 +197,7 @@ def restore!
Dispatcher.reset_application! Dispatcher.reset_application!
ActionController::Routing::Routes.reload ActionController::Routing::Routes.reload
end end
def breakpoint! def breakpoint!
require 'breakpoint' require 'breakpoint'
port = defined?(BREAKPOINT_SERVER_PORT) ? BREAKPOINT_SERVER_PORT : 42531 port = defined?(BREAKPOINT_SERVER_PORT) ? BREAKPOINT_SERVER_PORT : 42531
...@@ -197,14 +211,14 @@ def run_gc! ...@@ -197,14 +211,14 @@ def run_gc!
@gc_request_countdown = gc_request_period @gc_request_countdown = gc_request_period
GC.enable; GC.start; GC.disable GC.enable; GC.start; GC.disable
end end
def gc_countdown def gc_countdown
if gc_request_period if gc_request_period
@gc_request_countdown -= 1 @gc_request_countdown -= 1
run_gc! if @gc_request_countdown <= 0 run_gc! if @gc_request_countdown <= 0
end end
end end
def close_connection(cgi) def close_connection(cgi)
cgi.instance_variable_get("@request").finish cgi.instance_variable_get("@request").finish
end end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册