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:
parent
e63cf0903b
commit
fd9a2271ff
4 changed files with 28 additions and 22 deletions
|
@ -23,7 +23,8 @@ module Mongrel
|
|||
['-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', "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],
|
||||
['-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"],
|
||||
|
@ -174,7 +175,7 @@ module Mongrel
|
|||
def config_keys
|
||||
@config_keys ||=
|
||||
%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
|
||||
|
||||
def settings
|
||||
|
|
|
@ -547,6 +547,7 @@ module Mongrel
|
|||
attr_reader :classifier
|
||||
attr_reader :host
|
||||
attr_reader :port
|
||||
attr_reader :throttle
|
||||
attr_reader :timeout
|
||||
attr_reader :num_processors
|
||||
|
||||
|
@ -560,18 +561,18 @@ module Mongrel
|
|||
# way to deal with overload. Other schemes involve still parsing the client's request
|
||||
# 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
|
||||
# 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)
|
||||
@classifier = URIClassifier.new
|
||||
@host = host
|
||||
@port = port
|
||||
@workers = ThreadGroup.new
|
||||
@timeout = timeout
|
||||
@throttle = throttle
|
||||
@num_processors = num_processors
|
||||
@death_time = 60
|
||||
@timeout = timeout
|
||||
end
|
||||
|
||||
# Does the majority of the IO processing. It has been written in Ruby using
|
||||
|
@ -608,12 +609,13 @@ module Mongrel
|
|||
if handlers
|
||||
params[Const::PATH_INFO] = path_info
|
||||
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
|
||||
# meta-variables (see sections 4.1.8 and 4.1.9) may not identify the
|
||||
# ultimate source of the request. They identify the client for the
|
||||
# immediate request to the server; that client may be a proxy, gateway,
|
||||
# or other intermediary acting on behalf of the actual source client."
|
||||
|
||||
# From http://www.ietf.org/rfc/rfc3875 :
|
||||
# "Script authors should be aware that the REMOTE_ADDR and REMOTE_HOST
|
||||
# meta-variables (see sections 4.1.8 and 4.1.9) may not identify the
|
||||
# ultimate source of the request. They identify the client for the
|
||||
# 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
|
||||
|
||||
# select handlers that want more detailed request notification
|
||||
|
@ -683,7 +685,7 @@ module Mongrel
|
|||
@workers.list.each do |w|
|
||||
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."
|
||||
w.raise(TimeoutError.new(error_msg))
|
||||
end
|
||||
|
@ -694,13 +696,13 @@ module Mongrel
|
|||
end
|
||||
|
||||
# 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
|
||||
# allow setting. The @timeout setting does extend this waiting period by
|
||||
# too long. It waits by @timeout seconds, which can be set in .initialize or
|
||||
# via mongrel_rails. The @throttle setting does extend this waiting period by
|
||||
# that much longer.
|
||||
def graceful_shutdown
|
||||
while reap_dead_workers("shutdown") > 0
|
||||
STDERR.print "Waiting for #{@workers.list.length} requests to finish, could take #{@death_time + @timeout} seconds."
|
||||
sleep @death_time / 10
|
||||
STDERR.print "Waiting for #{@workers.list.length} requests to finish, could take #{@timeout + @throttle} seconds."
|
||||
sleep @timeout / 10
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -752,7 +754,7 @@ module Mongrel
|
|||
thread[:started_on] = Time.now
|
||||
@workers.add(thread)
|
||||
|
||||
sleep @timeout/100 if @timeout > 0
|
||||
sleep @throttle/100.0 if @throttle > 0
|
||||
end
|
||||
rescue StopServer
|
||||
@socket.close rescue nil
|
||||
|
|
|
@ -119,8 +119,9 @@ module Mongrel
|
|||
#
|
||||
# * :host => Host name to bind.
|
||||
# * :port => Port to bind.
|
||||
# * :num_processors => The maximum number of concurrent threads allowed. (950 default)
|
||||
# * :timeout => 1/100th of a second timeout between requests. (10 is 1/10th, 0 is timeout)
|
||||
# * :num_processors => The maximum number of concurrent threads allowed.
|
||||
# * :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.
|
||||
# * :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)
|
||||
ops = resolve_defaults(options)
|
||||
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]}"
|
||||
@listeners[@listener_name] = @listener
|
||||
|
||||
|
|
|
@ -374,6 +374,7 @@ module Mongrel
|
|||
results << table("settings", [
|
||||
["host",listener.host],
|
||||
["port",listener.port],
|
||||
["throttle",listener.throttle],
|
||||
["timeout",listener.timeout],
|
||||
["workers max",listener.num_processors],
|
||||
])
|
||||
|
|
Loading…
Reference in a new issue