about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--bin/mongrel_rails5
-rw-r--r--lib/mongrel.rb34
-rw-r--r--lib/mongrel/configurator.rb10
-rw-r--r--lib/mongrel/handlers.rb1
4 files changed, 28 insertions, 22 deletions
diff --git a/bin/mongrel_rails b/bin/mongrel_rails
index bf8379b..9b343b3 100644
--- a/bin/mongrel_rails
+++ b/bin/mongrel_rails
@@ -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
diff --git a/lib/mongrel.rb b/lib/mongrel.rb
index dc8d16e..5ed1e66 100644
--- a/lib/mongrel.rb
+++ b/lib/mongrel.rb
@@ -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
diff --git a/lib/mongrel/configurator.rb b/lib/mongrel/configurator.rb
index 4fd81d6..9886634 100644
--- a/lib/mongrel/configurator.rb
+++ b/lib/mongrel/configurator.rb
@@ -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
 
diff --git a/lib/mongrel/handlers.rb b/lib/mongrel/handlers.rb
index be7860a..60472a8 100644
--- a/lib/mongrel/handlers.rb
+++ b/lib/mongrel/handlers.rb
@@ -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],
       ])