aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/fcgi_handler.rb
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2007-09-23 11:20:25 +0000
committerJeremy Kemper <jeremy@bitsweat.net>2007-09-23 11:20:25 +0000
commit547447ad2abf72f6f5eb57a76b1a830feca34d90 (patch)
tree9fd1c0e044e8873b46e22561fedb57405e8e9d73 /railties/lib/fcgi_handler.rb
parent4e3ed5bc44f6cd20c9e353ab63fd24b92a7942be (diff)
downloadrails-547447ad2abf72f6f5eb57a76b1a830feca34d90.tar.gz
rails-547447ad2abf72f6f5eb57a76b1a830feca34d90.tar.bz2
rails-547447ad2abf72f6f5eb57a76b1a830feca34d90.zip
RailsFCGIHandler tests. Closes #9630.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7593 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'railties/lib/fcgi_handler.rb')
-rw-r--r--railties/lib/fcgi_handler.rb130
1 files changed, 68 insertions, 62 deletions
diff --git a/railties/lib/fcgi_handler.rb b/railties/lib/fcgi_handler.rb
index 5bb26e4598..2b0d7b1916 100644
--- a/railties/lib/fcgi_handler.rb
+++ b/railties/lib/fcgi_handler.rb
@@ -41,38 +41,72 @@ class RailsFCGIHandler
# Start error timestamp at 11 seconds ago.
@last_error_on = Time.now - 11
-
- dispatcher_log :info, "starting"
end
def process!(provider = FCGI)
- # Make a note of $" so we can safely reload this instance.
- mark!
-
- run_gc! if gc_request_period
+ mark_features!
+
+ dispatcher_log :info, 'starting'
+ process_each_request provider
+ dispatcher_log :info, 'stopping gracefully'
+
+ rescue Exception => error
+ case error
+ when SystemExit
+ dispatcher_log :info, 'stopping after explicit exit'
+ when SignalException
+ dispatcher_error error, 'stopping after unhandled signal'
+ else
+ # Retry if exceptions occur more than 10 seconds apart.
+ if Time.now - @last_error_on > 10
+ @last_error_on = Time.now
+ dispatcher_error error, 'retrying after unhandled exception'
+ retry
+ else
+ dispatcher_error error, 'stopping after unhandled exception within 10 seconds of the last'
+ end
+ end
+ end
- process_each_request!(provider)
- GC.enable
- dispatcher_log :info, "terminated gracefully"
+ protected
+ def process_each_request(provider)
+ cgi = nil
- rescue SystemExit => exit_error
- dispatcher_log :info, "terminated by explicit exit"
+ provider.each_cgi do |cgi|
+ process_request(cgi)
- rescue Exception => fcgi_error # FCGI errors
- # retry on errors that would otherwise have terminated the FCGI process,
- # but only if they occur more than 10 seconds apart.
- if !(SignalException === fcgi_error) && Time.now - @last_error_on > 10
- @last_error_on = Time.now
- dispatcher_error(fcgi_error, "almost killed by this error")
- retry
- else
- dispatcher_error(fcgi_error, "killed by this error")
+ case when_ready
+ when :reload
+ reload!
+ when :restart
+ close_connection(cgi)
+ restart!
+ when :exit
+ close_connection(cgi)
+ break
+ end
+ end
+ rescue SignalException => signal
+ raise unless signal.message == 'SIGUSR1'
+ close_connection(cgi)
end
- end
+ def process_request(cgi)
+ @when_ready = nil
+ gc_countdown
+
+ with_signal_handler 'USR1' do
+ begin
+ Dispatcher.dispatch(cgi)
+ rescue SignalException, SystemExit
+ raise
+ rescue Exception => error
+ dispatcher_error error, 'unhandled dispatch error'
+ end
+ end
+ end
- protected
def logger
@logger ||= Logger.new(@log_file_path)
end
@@ -97,10 +131,12 @@ class RailsFCGIHandler
end
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}."
+ if SIGNALS.include?(signal) && self.class.method_defined?(name = "#{SIGNALS[signal]}_handler")
+ handler ||= method(name).to_proc
+ trap(signal, handler)
+ else
+ dispatcher_log :warn, "Ignoring unsupported signal #{signal}."
+ end
end
def with_signal_handler(signal)
@@ -111,12 +147,12 @@ class RailsFCGIHandler
end
def exit_now_handler(signal)
- dispatcher_log :info, "asked to terminate immediately"
+ dispatcher_log :info, "asked to stop immediately"
exit
end
def exit_handler(signal)
- dispatcher_log :info, "asked to terminate ASAP"
+ dispatcher_log :info, "asked to stop ASAP"
@when_ready = :exit
end
@@ -130,38 +166,6 @@ class RailsFCGIHandler
@when_ready = :restart
end
- def process_each_request!(provider)
- cgi = nil
- provider.each_cgi do |cgi|
- with_signal_handler 'USR1' do
- process_request(cgi)
- end
-
- case when_ready
- when :reload
- reload!
- when :restart
- close_connection(cgi)
- restart!
- when :exit
- close_connection(cgi)
- break
- end
-
- gc_countdown
- end
- rescue SignalException => signal
- raise unless signal.message == 'SIGUSR1'
- close_connection(cgi) if cgi
- end
-
- def process_request(cgi)
- Dispatcher.dispatch(cgi)
- rescue Exception => e # errors from CGI dispatch
- raise if SignalException === e
- dispatcher_error(e)
- end
-
def restart!
config = ::Config::CONFIG
ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT']
@@ -184,7 +188,8 @@ class RailsFCGIHandler
dispatcher_log :info, "reloaded"
end
- def mark!
+ # Make a note of $" so we can safely reload this instance.
+ def mark_features!
@features = $".clone
end
@@ -201,12 +206,13 @@ class RailsFCGIHandler
def gc_countdown
if gc_request_period
+ @gc_request_countdown ||= 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
+ cgi.instance_variable_get("@request").finish if cgi
end
end