diff --git a/lib/mongrel.rb b/lib/mongrel.rb index 72685aeb..b55c095d 100644 --- a/lib/mongrel.rb +++ b/lib/mongrel.rb @@ -89,7 +89,10 @@ module Mongrel # 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=950, throttle=0, timeout=60) + + tries = 0 @socket = TCPServer.new(host, port) + @classifier = URIClassifier.new @host = host @port = port @@ -211,12 +214,12 @@ module Mongrel STDERR.puts "#{Time.now}: Reaping #{@workers.list.length} threads for slow workers because of '#{reason}'" error_msg = "Mongrel timed out this thread: #{reason}" mark = Time.now - @workers.list.each do |w| - w[:started_on] = Time.now if not w[:started_on] + @workers.list.each do |worker| + worker[:started_on] = Time.now if not worker[:started_on] - if mark - w[:started_on] > @timeout + @throttle + if mark - worker[:started_on] > @timeout + @throttle STDERR.puts "Thread #{w.inspect} is too old, killing." - w.raise(TimeoutError.new(error_msg)) + worker.raise(TimeoutError.new(error_msg)) end end end @@ -264,42 +267,46 @@ module Mongrel end @acceptor = Thread.new do - while true - begin - client = @socket.accept - - if defined?($tcp_cork_opts) and $tcp_cork_opts - client.setsockopt(*$tcp_cork_opts) rescue nil - end - - worker_list = @workers.list - - if worker_list.length >= @num_processors - STDERR.puts "Server overloaded with #{worker_list.length} processors (#@num_processors max). Dropping connection." + begin + while true + begin + client = @socket.accept + + if defined?($tcp_cork_opts) and $tcp_cork_opts + client.setsockopt(*$tcp_cork_opts) rescue nil + end + + worker_list = @workers.list + + if worker_list.length >= @num_processors + STDERR.puts "Server overloaded with #{worker_list.length} processors (#@num_processors max). Dropping connection." + client.close rescue nil + reap_dead_workers("max processors") + else + thread = Thread.new(client) {|c| process_client(c) } + thread[:started_on] = Time.now + @workers.add(thread) + + sleep @throttle/100.0 if @throttle > 0 + end + rescue StopServer + break + rescue Errno::EMFILE + reap_dead_workers("too many open files") + sleep 0.5 + rescue Errno::ECONNABORTED + # client closed the socket even before accept client.close rescue nil - reap_dead_workers("max processors") - else - thread = Thread.new(client) {|c| process_client(c) } - thread[:started_on] = Time.now - @workers.add(thread) - - sleep @throttle/100.0 if @throttle > 0 + rescue Object => e + STDERR.puts "#{Time.now}: Unhandled listen loop exception #{e.inspect}." + STDERR.puts e.backtrace.join("\n") end - rescue StopServer - @socket.close - break - rescue Errno::EMFILE - reap_dead_workers("too many open files") - sleep 0.5 - rescue Errno::ECONNABORTED - # client closed the socket even before accept - client.close rescue nil - rescue Object => e - STDERR.puts "#{Time.now}: Unhandled listen loop exception #{e.inspect}." - STDERR.puts e.backtrace.join("\n") end + graceful_shutdown + ensure + @socket.close + # STDERR.puts "#{Time.now}: Closed socket." end - graceful_shutdown end return @acceptor @@ -334,7 +341,7 @@ module Mongrel def stop(synchronous=false) @acceptor.raise(StopServer.new) - if synchronous + if synchronous sleep(0.5) while @acceptor.alive? end end diff --git a/test/test_redirect_handler.rb b/test/test_redirect_handler.rb index f9702037..2e03d483 100644 --- a/test/test_redirect_handler.rb +++ b/test/test_redirect_handler.rb @@ -9,7 +9,9 @@ require 'test/testhelp' class RedirectHandlerTest < Test::Unit::TestCase def setup - @server = Mongrel::HttpServer.new('127.0.0.1', 9998) + redirect_test_io do + @server = Mongrel::HttpServer.new('127.0.0.1', 9998) + end @server.run @client = Net::HTTP.new('127.0.0.1', 9998) end diff --git a/test/test_request_progress.rb b/test/test_request_progress.rb index e9801735..ba21c271 100644 --- a/test/test_request_progress.rb +++ b/test/test_request_progress.rb @@ -38,7 +38,9 @@ end class RequestProgressTest < Test::Unit::TestCase def setup - @server = Mongrel::HttpServer.new("127.0.0.1", 9998) + redirect_test_io do + @server = Mongrel::HttpServer.new("127.0.0.1", 9998) + end @handler = UploadBeginHandler.new @server.register("/upload", @handler) @server.run diff --git a/test/test_ws.rb b/test/test_ws.rb index 33981c67..7aa6db55 100644 --- a/test/test_ws.rb +++ b/test/test_ws.rb @@ -22,9 +22,12 @@ class WebServerTest < Test::Unit::TestCase def setup @valid_request = "GET / HTTP/1.1\r\nHost: www.zedshaw.com\r\nContent-Type: text/plain\r\n\r\n" - - # We set num_processors=1 so that we can test the reaping code - @server = HttpServer.new("127.0.0.1", 9998, num_processors=1) + + redirect_test_io do + # We set num_processors=1 so that we can test the reaping code + @server = HttpServer.new("127.0.0.1", 9998, num_processors=1) + end + @tester = TestHandler.new @server.register("/test", @tester) redirect_test_io do