mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
6c473eb410
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1284 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
69 lines
No EOL
2.3 KiB
Ruby
Executable file
69 lines
No EOL
2.3 KiB
Ruby
Executable file
#!/usr/local/bin/ruby
|
|
|
|
def dispatcher_log(level, path,msg)
|
|
Logger.new(path).send(level, msg)
|
|
rescue Object => log_error
|
|
STDERR << "Couldn't write to #{path}: #{msg}"
|
|
end
|
|
|
|
def dispatcher_error(path,e,msg="")
|
|
error_message =
|
|
"[#{Time.now}] Dispatcher failed to catch: #{e} (#{e.class})\n #{e.backtrace.join("\n ")}\n#{msg}"
|
|
dispatcher_log(:error, path, error_message)
|
|
end
|
|
|
|
last_error_on = nil
|
|
begin
|
|
require File.dirname(__FILE__) + "/../config/environment"
|
|
require 'dispatcher'
|
|
require 'fcgi'
|
|
|
|
log_file_path = "#{RAILS_ROOT}/log/fastcgi.crash.log"
|
|
dispatcher_log(:info, log_file_path, "fcgi #{$$} starting")
|
|
|
|
# Allow graceful exits by sending the process SIGUSR1. If the process is
|
|
# currently handling a request, the request will be allowed to complete and
|
|
# then will terminate itself. If a request is not being handled, the
|
|
# process is terminated immediately (via #exit).
|
|
|
|
$please_exit_at_your_earliest_convenience = false
|
|
$i_am_currently_processing_a_request = false
|
|
trap("USR1") do
|
|
if $i_am_currently_processing_a_request
|
|
dispatcher_log(:info, log_file_path, "asking #{$$} to terminate ASAP")
|
|
$please_exit_at_your_earliest_convenience = true
|
|
else
|
|
dispatcher_log(:info, log_file_path, "telling #{$$} to terminate NOW")
|
|
exit
|
|
end
|
|
end
|
|
|
|
# Process each request as it comes in, as a pseudo-CGI.
|
|
|
|
FCGI.each_cgi do |cgi|
|
|
begin
|
|
$i_am_currently_processing_a_request = true
|
|
Dispatcher.dispatch(cgi)
|
|
rescue Object => e
|
|
dispatcher_error(log_file_path, e)
|
|
ensure
|
|
$stdout.flush
|
|
$i_am_currently_processing_a_request = false
|
|
break if $please_exit_at_your_earliest_convenience
|
|
end
|
|
end
|
|
|
|
dispatcher_log(:info, log_file_path, "fcgi #{$$} terminated gracefully")
|
|
rescue SystemExit => exit_error
|
|
dispatcher_log(:info, log_file_path, "fcgi #{$$} terminated by explicit exit")
|
|
rescue Object => fcgi_error
|
|
# 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) && (last_error_on.nil? || last_error_on - Time.now > 10)
|
|
last_error_on = Time.now
|
|
dispatcher_error(log_file_path, fcgi_error, "FCGI process #{$$} almost killed by this error\n")
|
|
retry
|
|
else
|
|
dispatcher_error(log_file_path, fcgi_error, "FCGI process #{$$} killed by this error\n")
|
|
end
|
|
end |