1
0
Fork 0
mirror of https://github.com/puma/puma.git synced 2022-11-09 13:48:40 -05:00

Mongrel 0.3.13.5 version bump. Final commit of changes from 0.3.13.4. I've been ultra bad about commits.

git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@349 19e92222-5c0b-0410-8929-a290d50e31e9
This commit is contained in:
zedshaw 2006-09-22 08:16:54 +00:00
parent 5f0c661e6a
commit e1d423ab4d
11 changed files with 273 additions and 264 deletions

View file

@ -53,7 +53,7 @@ task :site => [:site_webgen, :site_rdoc, :site_coverage, :site_projects_rdoc]
setup_extension("http11", "http11")
name="mongrel"
version="0.3.13.4"
version="0.3.13.5"
setup_gem(name, version) do |spec|
spec.summary = "A small fast HTTP library and server that runs Rails, Camping, and Nitro apps."

View file

@ -10,216 +10,217 @@ require 'mongrel'
require 'mongrel/rails'
require 'etc'
module Mongrel
class Start < GemPlugin::Plugin "/commands"
include Mongrel::Command::Base
class Start < GemPlugin::Plugin "/commands"
include Mongrel::Command::Base
def configure
options [
["-e", "--environment ENV", "Rails environment to run as", :@environment, ENV['RAILS_ENV'] || "development"],
["-d", "--daemonize", "Whether to run in the background or not", :@daemon, false],
['-p', '--port PORT', "Which port to bind to", :@port, 3000],
['-a', '--address ADDR', "Address to bind to", :@address, "0.0.0.0"],
['-l', '--log FILE', "Where to write log messages", :@log_file, "log/mongrel.log"],
['-P', '--pid FILE', "Where to write the PID", :@pid_file, "log/mongrel.pid"],
['-n', '--num-procs INT', "Number of processors active before clients denied", :@num_procs, 1024],
['-t', '--timeout TIME', "Timeout all requests after 100th seconds time", :@timeout, 0],
['-m', '--mime PATH', "A YAML file that lists additional MIME types", :@mime_map, nil],
['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, Dir.pwd],
['-r', '--root PATH', "Set the document root (default 'public')", :@docroot, "public"],
['-B', '--debug', "Enable debugging mode", :@debug, false],
['-C', '--config PATH', "Use a config file", :@config_file, nil],
['-S', '--script PATH', "Load the given file as an extra config script.", :@config_script, nil],
['-G', '--generate CONFIG', "Generate a config file for -C", :@generate, nil],
['', '--user USER', "User to run as", :@user, nil],
['', '--group GROUP', "Group to run as", :@group, nil],
['', '--prefix PATH', "URL prefix for Rails app", :@prefix, nil]
]
end
def validate
@cwd = File.expand_path(@cwd)
valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
# change there to start, then we'll have to come back after daemonize
Dir.chdir(@cwd)
valid?(@prefix[0].chr == "/" && @prefix[-1].chr != "/", "Prefix must begin with / and not end in /") if @prefix
valid_dir? File.dirname(@log_file), "Path to log file not valid: #@log_file"
valid_dir? File.dirname(@pid_file), "Path to pid file not valid: #@pid_file"
valid_dir? @docroot, "Path to docroot not valid: #@docroot"
valid_exists? @mime_map, "MIME mapping file does not exist: #@mime_map" if @mime_map
valid_exists? @config_file, "Config file not there: #@config_file" if @config_file
valid_dir? File.dirname(@generate), "Problem accessing directory to #@generate" if @generate
valid_user? @user if @user
valid_group? @group if @group
return @valid
end
def run
# command line setting override config file settings
settings = { :host => @address, :port => @port, :cwd => @cwd,
:log_file => @log_file, :pid_file => @pid_file, :environment => @environment,
:docroot => @docroot, :mime_map => @mime_map, :daemon => @daemon,
:debug => @debug, :includes => ["mongrel"], :config_script => @config_script,
:num_processors => @num_procs, :timeout => @timeout,
:user => @user, :group => @group, :prefix => @prefix, :config_file => @config_file
}
if @generate
STDERR.puts "** Writing config to #@generate"
open(@generate, "w") {|f| f.write(settings.to_yaml) }
STDERR.puts "## Exiting. Re-run without -G and WITH -C using your new config file."
exit 0
def configure
options [
["-e", "--environment ENV", "Rails environment to run as", :@environment, ENV['RAILS_ENV'] || "development"],
["-d", "--daemonize", "Whether to run in the background or not", :@daemon, false],
['-p', '--port PORT', "Which port to bind to", :@port, 3000],
['-a', '--address ADDR', "Address to bind to", :@address, "0.0.0.0"],
['-l', '--log FILE', "Where to write log messages", :@log_file, "log/mongrel.log"],
['-P', '--pid FILE', "Where to write the PID", :@pid_file, "log/mongrel.pid"],
['-n', '--num-procs INT', "Number of processors active before clients denied", :@num_procs, 1024],
['-t', '--timeout TIME', "Timeout all requests after 100th seconds time", :@timeout, 0],
['-m', '--mime PATH', "A YAML file that lists additional MIME types", :@mime_map, nil],
['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, Dir.pwd],
['-r', '--root PATH', "Set the document root (default 'public')", :@docroot, "public"],
['-B', '--debug', "Enable debugging mode", :@debug, false],
['-C', '--config PATH', "Use a config file", :@config_file, nil],
['-S', '--script PATH', "Load the given file as an extra config script.", :@config_script, nil],
['-G', '--generate CONFIG', "Generate a config file for -C", :@generate, nil],
['', '--user USER', "User to run as", :@user, nil],
['', '--group GROUP', "Group to run as", :@group, nil],
['', '--prefix PATH', "URL prefix for Rails app", :@prefix, nil]
]
end
if @config_file
conf = YAML.load_file(@config_file)
settings = settings.merge! conf
STDERR.puts "** Loading settings from #{@config_file} (they override command line)." unless settings[:daemon]
def validate
@cwd = File.expand_path(@cwd)
valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
# change there to start, then we'll have to come back after daemonize
Dir.chdir(@cwd)
valid?(@prefix[0].chr == "/" && @prefix[-1].chr != "/", "Prefix must begin with / and not end in /") if @prefix
valid_dir? File.dirname(@log_file), "Path to log file not valid: #@log_file"
valid_dir? File.dirname(@pid_file), "Path to pid file not valid: #@pid_file"
valid_dir? @docroot, "Path to docroot not valid: #@docroot"
valid_exists? @mime_map, "MIME mapping file does not exist: #@mime_map" if @mime_map
valid_exists? @config_file, "Config file not there: #@config_file" if @config_file
valid_dir? File.dirname(@generate), "Problem accessing directory to #@generate" if @generate
valid_user? @user if @user
valid_group? @group if @group
return @valid
end
config = Mongrel::Rails::RailsConfigurator.new(settings) do
if defaults[:daemon]
if File.exist? defaults[:pid_file]
log "!!! PID file #{defaults[:pid_file]} already exists. Mongrel could be running already. Check your #{defaults[:log_file]} for errors."
end
daemonize
log "Daemonized, any open files are closed. Look at #{defaults[:pid_file]} and #{defaults[:log_file]} for info."
log "Settings loaded from #{@config_file} (they override command line)." if @config_file
def run
# command line setting override config file settings
settings = { :host => @address, :port => @port, :cwd => @cwd,
:log_file => @log_file, :pid_file => @pid_file, :environment => @environment,
:docroot => @docroot, :mime_map => @mime_map, :daemon => @daemon,
:debug => @debug, :includes => ["mongrel"], :config_script => @config_script,
:num_processors => @num_procs, :timeout => @timeout,
:user => @user, :group => @group, :prefix => @prefix, :config_file => @config_file
}
if @generate
STDERR.puts "** Writing config to #@generate"
open(@generate, "w") {|f| f.write(settings.to_yaml) }
STDERR.puts "## Exiting. Re-run without -G and WITH -C using your new config file."
exit 0
end
log "Starting Mongrel listening at #{defaults[:host]}:#{defaults[:port]}"
listener do
mime = {}
if defaults[:mime_map]
log "Loading additional MIME types from #{defaults[:mime_map]}"
mime = load_mime_map(defaults[:mime_map], mime)
end
if defaults[:debug]
log "Installing debugging prefixed filters. Look in log/mongrel_debug for the files."
debug "/"
end
log "Starting Rails with #{defaults[:environment]} environment..."
log "Mounting Rails at #{defaults[:prefix]}..." if defaults[:prefix]
uri defaults[:prefix] || "/", :handler => rails(:mime => mime, :prefix => defaults[:prefix])
log "Rails loaded."
log "Loading any Rails specific GemPlugins"
load_plugins
if defaults[:config_script]
log "Loading #{defaults[:config_script]} external config script"
run_config(defaults[:config_script])
end
setup_rails_signals
if @config_file
conf = YAML.load_file(@config_file)
settings = settings.merge! conf
STDERR.puts "** Loading settings from #{@config_file} (they override command line)." unless settings[:daemon]
end
end
config.run
config.log "Mongrel available at #{settings[:host]}:#{settings[:port]}"
if config.defaults[:daemon]
config.write_pid_file
else
config.log "Use CTRL-C to stop."
end
config = Mongrel::Rails::RailsConfigurator.new(settings) do
if defaults[:daemon]
if File.exist? defaults[:pid_file]
log "!!! PID file #{defaults[:pid_file]} already exists. Mongrel could be running already. Check your #{defaults[:log_file]} for errors."
end
config.join
daemonize
log "Daemonized, any open files are closed. Look at #{defaults[:pid_file]} and #{defaults[:log_file]} for info."
log "Settings loaded from #{@config_file} (they override command line)." if @config_file
end
if config.needs_restart
if RUBY_PLATFORM !~ /mswin/
cmd = "ruby #{__FILE__} start #{original_args.join(' ')}"
config.log "Restarting with arguments: #{cmd}"
exec cmd
log "Starting Mongrel listening at #{defaults[:host]}:#{defaults[:port]}"
listener do
mime = {}
if defaults[:mime_map]
log "Loading additional MIME types from #{defaults[:mime_map]}"
mime = load_mime_map(defaults[:mime_map], mime)
end
if defaults[:debug]
log "Installing debugging prefixed filters. Look in log/mongrel_debug for the files."
debug "/"
end
log "Starting Rails with #{defaults[:environment]} environment..."
log "Mounting Rails at #{defaults[:prefix]}..." if defaults[:prefix]
uri defaults[:prefix] || "/", :handler => rails(:mime => mime, :prefix => defaults[:prefix])
log "Rails loaded."
log "Loading any Rails specific GemPlugins"
load_plugins
if defaults[:config_script]
log "Loading #{defaults[:config_script]} external config script"
run_config(defaults[:config_script])
end
setup_rails_signals
end
end
config.run
config.log "Mongrel available at #{settings[:host]}:#{settings[:port]}"
if config.defaults[:daemon]
config.write_pid_file
else
config.log "Win32 does not support restarts. Exiting."
config.log "Use CTRL-C to stop."
end
config.join
if config.needs_restart
if RUBY_PLATFORM !~ /mswin/
cmd = "ruby #{__FILE__} start #{original_args.join(' ')}"
config.log "Restarting with arguments: #{cmd}"
exec cmd
else
config.log "Win32 does not support restarts. Exiting."
end
end
end
end
end
def send_signal(signal, pid_file)
pid = open(pid_file).read.to_i
print "Sending #{signal} to Mongrel at PID #{pid}..."
begin
Process.kill(signal, pid)
rescue Errno::ESRCH
puts "Process does not exist. Not running."
end
def Mongrel::send_signal(signal, pid_file)
pid = open(pid_file).read.to_i
print "Sending #{signal} to Mongrel at PID #{pid}..."
begin
Process.kill(signal, pid)
rescue Errno::ESRCH
puts "Process does not exist. Not running."
end
puts "Done."
end
class Stop < GemPlugin::Plugin "/commands"
include Mongrel::Command::Base
def configure
options [
['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, "."],
['-f', '--force', "Force the shutdown.", :@force, false],
['-P', '--pid FILE', "Where the PID file is located", :@pid_file, "log/mongrel.pid"]
]
end
def validate
@cwd = File.expand_path(@cwd)
valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
Dir.chdir @cwd
valid_exists? @pid_file, "PID file #@pid_file does not exist. Not running?"
return @valid
puts "Done."
end
def run
if @force
send_signal("KILL", @pid_file)
else
send_signal("TERM", @pid_file)
class Stop < GemPlugin::Plugin "/commands"
include Mongrel::Command::Base
def configure
options [
['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, "."],
['-f', '--force', "Force the shutdown.", :@force, false],
['-P', '--pid FILE', "Where the PID file is located", :@pid_file, "log/mongrel.pid"]
]
end
def validate
@cwd = File.expand_path(@cwd)
valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
Dir.chdir @cwd
valid_exists? @pid_file, "PID file #@pid_file does not exist. Not running?"
return @valid
end
def run
if @force
Mongrel::send_signal("KILL", @pid_file)
else
Mongrel::send_signal("TERM", @pid_file)
end
end
end
end
class Restart < GemPlugin::Plugin "/commands"
include Mongrel::Command::Base
class Restart < GemPlugin::Plugin "/commands"
include Mongrel::Command::Base
def configure
options [
['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, '.'],
['-s', '--soft', "Do a soft restart rather than a process exit restart", :@soft, false],
['-P', '--pid FILE', "Where the PID file is located", :@pid_file, "log/mongrel.pid"]
]
end
def configure
options [
['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, '.'],
['-s', '--soft', "Do a soft restart rather than a process exit restart", :@soft, false],
['-P', '--pid FILE', "Where the PID file is located", :@pid_file, "log/mongrel.pid"]
]
end
def validate
@cwd = File.expand_path(@cwd)
valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
def validate
@cwd = File.expand_path(@cwd)
valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
Dir.chdir @cwd
Dir.chdir @cwd
valid_exists? @pid_file, "PID file #@pid_file does not exist. Not running?"
return @valid
end
valid_exists? @pid_file, "PID file #@pid_file does not exist. Not running?"
return @valid
end
def run
if @soft
send_signal("HUP", @pid_file)
else
send_signal("USR2", @pid_file)
def run
if @soft
Mongrel::send_signal("HUP", @pid_file)
else
Mongrel::send_signal("USR2", @pid_file)
end
end
end
end
@ -227,10 +228,6 @@ end
GemPlugin::Manager.instance.load "mongrel" => GemPlugin::INCLUDE, "rails" => GemPlugin::EXCLUDE
if not Mongrel::Command::Registry.instance.run ARGV
exit 1
end

View file

@ -556,7 +556,7 @@ void Init_http11()
DEF_GLOBAL(server_protocol, "SERVER_PROTOCOL");
DEF_GLOBAL(server_protocol_value, "HTTP/1.1");
DEF_GLOBAL(http_host, "HTTP_HOST");
DEF_GLOBAL(mongrel_version, "Mongrel 0.3.13.4");
DEF_GLOBAL(mongrel_version, "Mongrel 0.3.13.5");
DEF_GLOBAL(server_software, "SERVER_SOFTWARE");
DEF_GLOBAL(port_80, "80");

View file

@ -117,7 +117,7 @@ module Mongrel
REQUEST_URI='REQUEST_URI'.freeze
REQUEST_PATH='REQUEST_PATH'.freeze
MONGREL_VERSION="0.3.13.4".freeze
MONGREL_VERSION="0.3.13.5".freeze
# TODO: this use of a base for tempfiles needs to be looked at for security problems
MONGREL_TMP_BASE="mongrel".freeze
@ -683,7 +683,7 @@ module Mongrel
client.close rescue Object
reap_dead_workers("max processors")
else
thread = Thread.new { process_client(client) }
thread = Thread.new(client) {|c| process_client(c) }
thread.abort_on_exception = true
thread[:started_on] = Time.now
@workers.add(thread)

View file

@ -157,6 +157,10 @@ module Mongrel
puts "#{Mongrel::Command::BANNER}\nAvailable commands are:\n\n"
self.commands.each do |name|
if /mongrel::/ =~ name
name = name[9 .. -1]
end
puts " - #{name[1 .. -1]}\n"
end
@ -179,8 +183,12 @@ module Mongrel
return true
end
# command exists, set it up and validate it
begin
# quick hack so that existing commands will keep working but the Mongrel:: ones can be moved
if ["start", "stop", "restart"].include? cmd_name
cmd_name = "mongrel::" + cmd_name
end
command = GemPlugin::Manager.instance.create("/commands/#{cmd_name}", :argv => args)
rescue OptionParser::InvalidOption
STDERR.puts "#$! for command '#{cmd_name}'"

View file

@ -302,17 +302,17 @@ module Mongrel
# debug "/", what = [:rails]
#
# And it will only produce the log/mongrel_debug/rails.log file.
# Available options are: :objects, :rails, :files, :threads, :params
# Available options are: :access, :files, :objects, :threads, :rails
#
# NOTE: Use [:files] to get accesses dumped to stderr like with WEBrick.
def debug(location, what = [:objects, :rails, :files, :threads, :params])
def debug(location, what = [:access, :files, :objects, :threads, :rails])
require 'mongrel/debug'
handlers = {
:files => "/handlers/requestlog::access",
:rails => "/handlers/requestlog::files",
:access => "/handlers/requestlog::access",
:files => "/handlers/requestlog::files",
:objects => "/handlers/requestlog::objects",
:threads => "/handlers/requestlog::threads",
:params => "/handlers/requestlog::params"
:rails => "/handlers/requestlog::params"
}
# turn on the debugging infrastructure, and ObjectTracker is a pig

View file

@ -129,7 +129,7 @@ module RequestLog
begin
if o.respond_to? :length
len = o.length
lengths[o.class] ||= Stats.new(o.class)
lengths[o.class] ||= Mongrel::Stats.new(o.class)
lengths[o.class].sample(len)
end
rescue Object

View file

@ -324,11 +324,11 @@ module Mongrel
def initialize(ops={})
@sample_rate = ops[:sample_rate] || 300
@processors = Stats.new("processors")
@reqsize = Stats.new("request Kb")
@headcount = Stats.new("req param count")
@respsize = Stats.new("response Kb")
@interreq = Stats.new("inter-request time")
@processors = Mongrel::Stats.new("processors")
@reqsize = Mongrel::Stats.new("request Kb")
@headcount = Mongrel::Stats.new("req param count")
@respsize = Mongrel::Stats.new("response Kb")
@interreq = Mongrel::Stats.new("inter-request time")
end

View file

@ -78,10 +78,12 @@ module Mongrel
# we don't want the output to be really final until we're out of the lock
cgi.default_really_final = false
log_threads_waiting_for(request.params["PATH_INFO"]) if $mongrel_debug_client
log_threads_waiting_for(request.params["PATH_INFO"] || @active_request_path) if $mongrel_debug_client
@guard.synchronize(:EX) {
@active_request_path = request.params["PATH_INFO"]
Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, response.body)
@active_request_path = nil
}
# This finalizes the output using the proper HttpResponse way

View file

@ -12,76 +12,78 @@
#
# It does all of this very fast and doesn't take up any memory since the samples
# are not stored but instead all the values are calculated on the fly.
class Stats
attr_reader :sum, :sumsq, :n, :min, :max
module Mongrel
class Stats
attr_reader :sum, :sumsq, :n, :min, :max
def initialize(name)
@name = name
reset
end
# Resets the internal counters so you can start sampling again.
def reset
@sum = 0.0
@sumsq = 0.0
@last_time = Time.new
@n = 0.0
@min = 0.0
@max = 0.0
end
# Adds a sampling to the calculations.
def sample(s)
@sum += s
@sumsq += s * s
if @n == 0
@min = @max = s
else
@min = s if @min > s
@max = s if @max < s
def initialize(name)
@name = name
reset
end
@n+=1
end
# Dump this Stats object with an optional additional message.
def dump(msg = "", out=STDERR)
out.puts "#{msg}: #{self.to_s}"
end
# Resets the internal counters so you can start sampling again.
def reset
@sum = 0.0
@sumsq = 0.0
@last_time = Time.new
@n = 0.0
@min = 0.0
@max = 0.0
end
# Returns a common display (used by dump)
def to_s
# Adds a sampling to the calculations.
def sample(s)
@sum += s
@sumsq += s * s
if @n == 0
@min = @max = s
else
@min = s if @min > s
@max = s if @max < s
end
@n+=1
end
# Dump this Stats object with an optional additional message.
def dump(msg = "", out=STDERR)
out.puts "#{msg}: #{self.to_s}"
end
# Returns a common display (used by dump)
def to_s
"[#{@name}]: SUM=%0.4f, SUMSQ=%0.4f, N=%0.4f, MEAN=%0.4f, SD=%0.4f, MIN=%0.4f, MAX=%0.4f" % [@sum, @sumsq, @n, mean, sd, @min, @max]
end
# Calculates and returns the mean for the data passed so far.
def mean
@sum / @n
end
# Calculates the standard deviation of the data so far.
def sd
# (sqrt( ((s).sumsq - ( (s).sum * (s).sum / (s).n)) / ((s).n-1) ))
begin
return Math.sqrt( (@sumsq - ( @sum * @sum / @n)) / (@n-1) )
rescue Errno::EDOM
return 0.0
end
end
# Adds a time delta between now and the last time you called this. This
# will give you the average time between two activities.
#
# An example is:
#
# t = Stats.new("do_stuff")
# 10000.times { do_stuff(); t.tick }
# t.dump("time")
#
def tick
now = Time.now
sample(now - @last_time)
@last_time = now
# Calculates and returns the mean for the data passed so far.
def mean
@sum / @n
end
# Calculates the standard deviation of the data so far.
def sd
# (sqrt( ((s).sumsq - ( (s).sum * (s).sum / (s).n)) / ((s).n-1) ))
begin
return Math.sqrt( (@sumsq - ( @sum * @sum / @n)) / (@n-1) )
rescue Errno::EDOM
return 0.0
end
end
# Adds a time delta between now and the last time you called this. This
# will give you the average time between two activities.
#
# An example is:
#
# t = Stats.new("do_stuff")
# 10000.times { do_stuff(); t.tick }
# t.dump("time")
#
def tick
now = Time.now
sample(now - @last_time)
@last_time = now
end
end
end

View file

@ -13,8 +13,8 @@ class StatsTest < Test::Unit::TestCase
def test_sampling_speed
out = StringIO.new
s = Stats.new("test")
t = Stats.new("time")
s = Mongrel::Stats.new("test")
t = Mongrel::Stats.new("time")
100.times { s.sample(rand(20)); t.tick }