提交 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*
* 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]
* 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 @@
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 @@ def dispatcher_error(e, msg = "")
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 @@ def breakpoint_handler(signal)
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 @@ def process_each_request!(provider)
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 @@ 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)
......@@ -183,7 +197,7 @@ def restore!
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 @@ def run_gc!
@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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册