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

refactor timeout and death_time to throttle and timeout, respectively, make throttle not be zero for sub-second timeouts, improve documentation, update long command-line flags

git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@624 19e92222-5c0b-0410-8929-a290d50e31e9
This commit is contained in:
evanweaver 2007-09-24 16:26:38 +00:00
parent e63cf0903b
commit fd9a2271ff
4 changed files with 28 additions and 22 deletions

View file

@ -23,7 +23,8 @@ module Mongrel
['-l', '--log FILE', "Where to write log messages", :@log_file, "log/mongrel.log"], ['-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"], ['-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], ['-n', '--num-procs INT', "Number of processors active before clients denied", :@num_procs, 1024],
['-t', '--timeout TIME', "Time to pause (in hundredths of a second) between accepting clients", :@timeout, 0], ['-o', '--timeout TIME', "Time to wait (in seconds) before killing a stalled thread", :@timeout, 0],
['-t', '--throttle TIME', "Time to pause (in hundredths of a second) between accepting clients", :@throttle, 0],
['-m', '--mime PATH', "A YAML file that lists additional MIME types", :@mime_map, nil], ['-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], ['-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"], ['-r', '--root PATH', "Set the document root (default 'public')", :@docroot, "public"],
@ -174,7 +175,7 @@ module Mongrel
def config_keys def config_keys
@config_keys ||= @config_keys ||=
%w(host port cwd log_file pid_file environment docroot mime_map daemon debug includes config_script %w(host port cwd log_file pid_file environment docroot mime_map daemon debug includes config_script
num_processors timeout user group prefix) num_processors timeout throttle user group prefix)
end end
def settings def settings

View file

@ -547,6 +547,7 @@ module Mongrel
attr_reader :classifier attr_reader :classifier
attr_reader :host attr_reader :host
attr_reader :port attr_reader :port
attr_reader :throttle
attr_reader :timeout attr_reader :timeout
attr_reader :num_processors attr_reader :num_processors
@ -560,18 +561,18 @@ module Mongrel
# way to deal with overload. Other schemes involve still parsing the client's request # way to deal with overload. Other schemes involve still parsing the client's request
# which defeats the point of an overload handling system. # which defeats the point of an overload handling system.
# #
# The timeout parameter is a sleep timeout (in hundredths of a second) that is placed between # The throttle parameter is a sleep timeout (in hundredths of a second) that is placed between
# socket.accept calls in order to give the server a cheap throttle time. It defaults to 0 and # socket.accept calls in order to give the server a cheap throttle time. It defaults to 0 and
# actually if it is 0 then the sleep is not done at all. # actually if it is 0 then the sleep is not done at all.
def initialize(host, port, num_processors=(2**30-1), timeout=0) def initialize(host, port, num_processors=950, throttle=0, timeout=60)
@socket = TCPServer.new(host, port) @socket = TCPServer.new(host, port)
@classifier = URIClassifier.new @classifier = URIClassifier.new
@host = host @host = host
@port = port @port = port
@workers = ThreadGroup.new @workers = ThreadGroup.new
@timeout = timeout @throttle = throttle
@num_processors = num_processors @num_processors = num_processors
@death_time = 60 @timeout = timeout
end end
# Does the majority of the IO processing. It has been written in Ruby using # Does the majority of the IO processing. It has been written in Ruby using
@ -608,12 +609,13 @@ module Mongrel
if handlers if handlers
params[Const::PATH_INFO] = path_info params[Const::PATH_INFO] = path_info
params[Const::SCRIPT_NAME] = script_name params[Const::SCRIPT_NAME] = script_name
# From http://www.ietf.org/rfc/rfc3875 :
# "Script authors should be aware that the REMOTE_ADDR and REMOTE_HOST # From http://www.ietf.org/rfc/rfc3875 :
# meta-variables (see sections 4.1.8 and 4.1.9) may not identify the # "Script authors should be aware that the REMOTE_ADDR and REMOTE_HOST
# ultimate source of the request. They identify the client for the # meta-variables (see sections 4.1.8 and 4.1.9) may not identify the
# immediate request to the server; that client may be a proxy, gateway, # ultimate source of the request. They identify the client for the
# or other intermediary acting on behalf of the actual source client." # immediate request to the server; that client may be a proxy, gateway,
# or other intermediary acting on behalf of the actual source client."
params[Const::REMOTE_ADDR] = client.peeraddr.last params[Const::REMOTE_ADDR] = client.peeraddr.last
# select handlers that want more detailed request notification # select handlers that want more detailed request notification
@ -683,7 +685,7 @@ module Mongrel
@workers.list.each do |w| @workers.list.each do |w|
w[:started_on] = Time.now if not w[:started_on] w[:started_on] = Time.now if not w[:started_on]
if mark - w[:started_on] > @death_time + @timeout if mark - w[:started_on] > @timeout + @throttle
STDERR.puts "Thread #{w.inspect} is too old, killing." STDERR.puts "Thread #{w.inspect} is too old, killing."
w.raise(TimeoutError.new(error_msg)) w.raise(TimeoutError.new(error_msg))
end end
@ -694,13 +696,13 @@ module Mongrel
end end
# Performs a wait on all the currently running threads and kills any that take # Performs a wait on all the currently running threads and kills any that take
# too long. Right now it just waits 60 seconds, but will expand this to # too long. It waits by @timeout seconds, which can be set in .initialize or
# allow setting. The @timeout setting does extend this waiting period by # via mongrel_rails. The @throttle setting does extend this waiting period by
# that much longer. # that much longer.
def graceful_shutdown def graceful_shutdown
while reap_dead_workers("shutdown") > 0 while reap_dead_workers("shutdown") > 0
STDERR.print "Waiting for #{@workers.list.length} requests to finish, could take #{@death_time + @timeout} seconds." STDERR.print "Waiting for #{@workers.list.length} requests to finish, could take #{@timeout + @throttle} seconds."
sleep @death_time / 10 sleep @timeout / 10
end end
end end
@ -752,7 +754,7 @@ module Mongrel
thread[:started_on] = Time.now thread[:started_on] = Time.now
@workers.add(thread) @workers.add(thread)
sleep @timeout/100 if @timeout > 0 sleep @throttle/100.0 if @throttle > 0
end end
rescue StopServer rescue StopServer
@socket.close rescue nil @socket.close rescue nil

View file

@ -119,8 +119,9 @@ module Mongrel
# #
# * :host => Host name to bind. # * :host => Host name to bind.
# * :port => Port to bind. # * :port => Port to bind.
# * :num_processors => The maximum number of concurrent threads allowed. (950 default) # * :num_processors => The maximum number of concurrent threads allowed.
# * :timeout => 1/100th of a second timeout between requests. (10 is 1/10th, 0 is timeout) # * :throttle => Time to pause (in hundredths of a second) between accepting clients.
# * :timeout => Time to wait (in seconds) before killing a stalled thread.
# * :user => User to change to, must have :group as well. # * :user => User to change to, must have :group as well.
# * :group => Group to change to, must have :user as well. # * :group => Group to change to, must have :user as well.
# #
@ -128,9 +129,10 @@ module Mongrel
raise "Cannot call listener inside another listener block." if (@listener or @listener_name) raise "Cannot call listener inside another listener block." if (@listener or @listener_name)
ops = resolve_defaults(options) ops = resolve_defaults(options)
ops[:num_processors] ||= 950 ops[:num_processors] ||= 950
ops[:timeout] ||= 0 ops[:throttle] ||= 0
ops[:timeout] ||= 60
@listener = Mongrel::HttpServer.new(ops[:host], ops[:port].to_i, ops[:num_processors].to_i, ops[:timeout].to_i) @listener = Mongrel::HttpServer.new(ops[:host], ops[:port].to_i, ops[:num_processors].to_i, ops[:throttle].to_i, ops[:timeout].to_i)
@listener_name = "#{ops[:host]}:#{ops[:port]}" @listener_name = "#{ops[:host]}:#{ops[:port]}"
@listeners[@listener_name] = @listener @listeners[@listener_name] = @listener

View file

@ -374,6 +374,7 @@ module Mongrel
results << table("settings", [ results << table("settings", [
["host",listener.host], ["host",listener.host],
["port",listener.port], ["port",listener.port],
["throttle",listener.throttle],
["timeout",listener.timeout], ["timeout",listener.timeout],
["workers max",listener.num_processors], ["workers max",listener.num_processors],
]) ])