rubyists-
i’ve collected some usefull examples and added some signal handling to the
fcgi package written by moon wolf. if any one has experience using fcgi out
there i appreciate any comments. highlights are
* reload any application using 'kill -HUP pid' w/o hanging apache
* gracefull shutdown from confusing SIGUSR1/SIGHUP combo sent by
apache/mod_fastcgi to fcgi programs
* clean exit on 'kill -TERM pid'
* each method which provides a CGI object
eg of use
MOD_FCGI.each(‘html3’) do |cgi|
content = ‘’
cgi.env_table.each do |k,v|
content << “#{k} → #{v}
\n”
end
cgi.out { cgi.html { cgi.body { content } } }
end
ps. this is named MOD_FCGI because, AFAIK this signal handling is specific to
apache’s mod_fastcgi
file : mod_fcgi.rb
----CUT----
require ‘fcgi’
require ‘cgi’
require ‘ftools’
class MOD_FCGI < FCGI
class Log < File
def tmpnam basename = nil,
tmpdir = ENV[‘TMPDIR’]||ENV[‘TMP’]||ENV[‘TEMP’]||‘/tmp’
if $SAFE > 0 and tmpdir.tainted?
tmpdir = ‘/tmp’
end
basename ||= File.basename $0
n = 0
while true
begin
path = sprintf(‘%s/%s%d.%d’, tmpdir, basename, $$, n)
@_lock = path + ‘.lock’
unless File.exist?(path) or File.exist?(@_lock)
Dir.mkdir(@_lock)
break
end
rescue
raise “cannot generate tempfile `%s’” % path if n >= 16
end
n += 1
end
path
end
def initialize path = tmpnam, mode = ‘w+’, &block
super path, mode, &block
Dir.rmdir(@_lock) if defined? @_lock
self.sync = true
end
end
enable CGI to bootstrap off of an FCGI request
class CGI < ::CGI
class << self
def remove_params
if (const_defined?(:CGI_PARAMS))
remove_const(:CGI_PARAMS)
remove_const(:CGI_COOKIES)
end
end
end
def initialize(request, *args)
self.class.remove_params
@request = request
super (*args)
@args = *args
end
def args
@args
end
def env_table
@request.env
end
def stdinput
@request.in
end
def stdoutput
@request.out
end
end
initialize mod_fcgi
@@handling_request = false
@@exit_requested = false
@@traps_installed = false
@@signals =
class << self
def handle_request
@@handling_request = true
yield if block_given?
ensure
@@handling_request = false
end
def install_traps
return if @@traps_installed
# user signal to reload application
# does a clean shutdown after which
# the fcgi_pm will reload of source file
trap ('SIGHUP') do
unless @@signals.size > 0
@@signals << 'SIGHUP'
if @@handling_request
@@exit_requested = true
else
@@server.close
exit
end
end
end
# sent from apache to do clean shutdown
# note that a sigterm could be sent from fcgi_pm
# AFTER this! we handle only one of them!
trap ('SIGUSR1') do
unless @@signals.size > 0
@@signals << 'SIGUSR1'
if @@handling_request
@@exit_requested = true
else
@@server.close
exit
end
end
end
# see above note.
# when no other signals pedning, simply exit quickly
trap ('SIGTERM') do
unless @@signals.size > 0
@@signals << 'SIGTERM'
@@server.close
exit
end
end
# sent from mod_fcgi when client aborts request
# we simply ignore this for now, although some smarts could be
# added to abort the present request and resume accepting...
trap ('SIGPIPE') do
# nothing
end
@@traps_installed = true
end
def each (*args)
install_traps
while request = accept
handle_request {
if block_given?
yield (CGI.new (request, *args))
request.finish
end
}
exit if @@exit_requested
end
end
alias each_request each
end
end
----CUT----
-a
···
–
====================================
Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================