From 72a315441937f9e0531112f2b7080da39ca6064d Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 30 Dec 2010 08:32:24 +0000 Subject: simplify per-client keepalive state checks This lets us simplify repetitive checks worry less about properly maintaining/closing client connections for each concurrency model we support. --- lib/rainbows.rb | 2 ++ lib/rainbows/coolio/client.rb | 2 +- lib/rainbows/coolio/thread_client.rb | 4 +--- lib/rainbows/ev_core.rb | 2 +- lib/rainbows/event_machine/client.rb | 2 +- lib/rainbows/http_parser.rb | 12 ++++++++++++ lib/rainbows/process_client.rb | 5 ++--- lib/rainbows/response.rb | 5 ++++- lib/rainbows/revactor.rb | 5 ++--- 9 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 lib/rainbows/http_parser.rb (limited to 'lib') diff --git a/lib/rainbows.rb b/lib/rainbows.rb index a503bf0..643bdd2 100644 --- a/lib/rainbows.rb +++ b/lib/rainbows.rb @@ -19,6 +19,7 @@ module Rainbows def quit! self.alive = false + Rainbows::HttpParser.quit self.expire ||= Time.now + (server.timeout * 2.0) server.class.const_get(:LISTENERS).map! { |s| s.close rescue nil } false @@ -36,6 +37,7 @@ module Rainbows # :startdoc: require 'rainbows/const' + require 'rainbows/http_parser' require 'rainbows/http_server' require 'rainbows/response' require 'rainbows/client' diff --git a/lib/rainbows/coolio/client.rb b/lib/rainbows/coolio/client.rb index 7ecea3c..7b41026 100644 --- a/lib/rainbows/coolio/client.rb +++ b/lib/rainbows/coolio/client.rb @@ -125,7 +125,7 @@ class Rainbows::Coolio::Client < Coolio::IO @env[REMOTE_ADDR] = @_io.kgio_addr response = APP.call(@env.update(RACK_DEFAULTS)) - coolio_write_response(response, alive = @hp.next? && G.alive) + coolio_write_response(response, alive = @hp.next?) return quit unless alive && :close != @state @state = :headers disable if enabled? diff --git a/lib/rainbows/coolio/thread_client.rb b/lib/rainbows/coolio/thread_client.rb index 3ada7bf..e6db2bd 100644 --- a/lib/rainbows/coolio/thread_client.rb +++ b/lib/rainbows/coolio/thread_client.rb @@ -14,10 +14,8 @@ class Rainbows::Coolio::ThreadClient < Rainbows::Coolio::Client # this is only called in the master thread def response_write(response) - alive = @hp.next? && G.alive - coolio_write_response(response, alive) + coolio_write_response(response, alive = @hp.next?) return quit unless alive && :close != @state - @state = :headers rescue => e handle_error(e) diff --git a/lib/rainbows/ev_core.rb b/lib/rainbows/ev_core.rb index 6f1b5e5..60fbdca 100644 --- a/lib/rainbows/ev_core.rb +++ b/lib/rainbows/ev_core.rb @@ -6,7 +6,7 @@ module Rainbows::EvCore include Rainbows::Response G = Rainbows::G NULL_IO = Unicorn::HttpRequest::NULL_IO - HttpParser = Unicorn::HttpParser + HttpParser = Rainbows::HttpParser autoload :CapInput, 'rainbows/ev_core/cap_input' # Apps may return this Rack response: AsyncResponse = [ -1, {}, [] ] diff --git a/lib/rainbows/event_machine/client.rb b/lib/rainbows/event_machine/client.rb index 49552f3..0b46b42 100644 --- a/lib/rainbows/event_machine/client.rb +++ b/lib/rainbows/event_machine/client.rb @@ -45,7 +45,7 @@ class Rainbows::EventMachine::Client < EM::Connection # long-running async response (response.nil? || -1 == response[0]) and return @state = :close - if @hp.next? && G.alive && G.kato > 0 + if @hp.next? @state = :headers em_write_response(response, true) if @buf.empty? diff --git a/lib/rainbows/http_parser.rb b/lib/rainbows/http_parser.rb new file mode 100644 index 0000000..ec55fe9 --- /dev/null +++ b/lib/rainbows/http_parser.rb @@ -0,0 +1,12 @@ +# -*- encoding: binary -*- +# :enddoc: +# avoid modifying Unicorn::HttpParser +class Rainbows::HttpParser < Unicorn::HttpParser + def self.quit + alias_method :next?, :never! + end + + def never! + false + end +end diff --git a/lib/rainbows/process_client.rb b/lib/rainbows/process_client.rb index 271185d..54e59e8 100644 --- a/lib/rainbows/process_client.rb +++ b/lib/rainbows/process_client.rb @@ -4,7 +4,7 @@ require 'rainbows/rack_input' module Rainbows::ProcessClient G = Rainbows::G include Rainbows::Response - HttpParser = Unicorn::HttpParser + HttpParser = Rainbows::HttpParser include Rainbows::RackInput include Rainbows::Const @@ -37,8 +37,7 @@ module Rainbows::ProcessClient if hp.headers? headers = HH.new(headers) range = make_range!(env, status, headers) and status = range.shift - alive = hp.next? && G.alive - headers[CONNECTION] = alive ? KEEP_ALIVE : CLOSE + headers[CONNECTION] = (alive = hp.next?) ? KEEP_ALIVE : CLOSE client.write(response_header(status, headers)) end write_body(client, body, range) diff --git a/lib/rainbows/response.rb b/lib/rainbows/response.rb index 8be4177..ca381b8 100644 --- a/lib/rainbows/response.rb +++ b/lib/rainbows/response.rb @@ -34,7 +34,10 @@ module Rainbows::Response # called after forking def self.setup(klass) - Rainbows::G.kato == 0 and KEEP_ALIVE.replace(CLOSE) + if 0 == Rainbows::G.kato + KEEP_ALIVE.replace(CLOSE) + Rainbows::HttpParser.keepalive_requests = 0 + end range_class = body_class = klass case Rainbows::Const::RACK_DEFAULTS['rainbows.model'] when :WriterThreadSpawn diff --git a/lib/rainbows/revactor.rb b/lib/rainbows/revactor.rb index d996243..f4e8fca 100644 --- a/lib/rainbows/revactor.rb +++ b/lib/rainbows/revactor.rb @@ -42,7 +42,7 @@ module Rainbows::Revactor else LOCALHOST end - hp = Unicorn::HttpParser.new + hp = Rainbows::HttpParser.new buf = hp.buf alive = false @@ -67,8 +67,7 @@ module Rainbows::Revactor if hp.headers? headers = HH.new(headers) range = make_range!(env, status, headers) and status = range.shift - alive = hp.next? && G.alive && G.kato > 0 - headers[CONNECTION] = alive ? KEEP_ALIVE : CLOSE + headers[CONNECTION] = (alive = hp.next?) ? KEEP_ALIVE : CLOSE client.write(response_header(status, headers)) alive && ts and buf << ts.leftover end -- cgit v1.2.3-24-ge0c7