about summary refs log tree commit homepage
path: root/lib/rainbows/revactor.rb
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-12-30 08:33:15 +0000
committerEric Wong <normalperson@yhbt.net>2011-01-04 16:37:42 -0800
commite21939d776673b2f8887adf7a5c64812b7d2e98e (patch)
tree48aa3a71201e770758bd09b325c3f2704411af7f /lib/rainbows/revactor.rb
parent4a76da1833922c74e147be5def9bfe04fd0c16a2 (diff)
downloadrainbows-e21939d776673b2f8887adf7a5c64812b7d2e98e.tar.gz
Rack::Utils::HeaderHash is still very expensive in Rack 1.2,
especially for simple things that we want to run as fast as
possible with minimal interference.  HeaderHash is unnecessary
for most requests that do not send Content-Range in responses.
Diffstat (limited to 'lib/rainbows/revactor.rb')
-rw-r--r--lib/rainbows/revactor.rb65
1 files changed, 3 insertions, 62 deletions
diff --git a/lib/rainbows/revactor.rb b/lib/rainbows/revactor.rb
index f4e8fca..be4badf 100644
--- a/lib/rainbows/revactor.rb
+++ b/lib/rainbows/revactor.rb
@@ -19,76 +19,17 @@ Revactor::VERSION >= '0.1.5' or abort 'revactor 0.1.5 is required'
 # \Revactor library as well, to take advantage of the networking
 # concurrency features this model provides.
 module Rainbows::Revactor
-
-  # :stopdoc:
-  RD_ARGS = {}
-
+  autoload :Client, 'rainbows/revactor/client'
   autoload :Proxy, 'rainbows/revactor/proxy'
-  autoload :TeeSocket, 'rainbows/revactor/tee_socket'
 
   include Rainbows::Base
-  LOCALHOST = Kgio::LOCALHOST
-  TCP = Revactor::TCP::Socket
-
-  # once a client is accepted, it is processed in its entirety here
-  # in 3 easy steps: read request, call app, write app response
-  def process_client(client) # :nodoc:
-    io = client.instance_variable_get(:@_io)
-    io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
-    rd_args = [ nil ]
-    remote_addr = if TCP === client
-      rd_args << RD_ARGS
-      client.remote_addr
-    else
-      LOCALHOST
-    end
-    hp = Rainbows::HttpParser.new
-    buf = hp.buf
-    alive = false
-
-    begin
-      ts = nil
-      until env = hp.parse
-        buf << client.read(*rd_args)
-      end
-
-      env[CLIENT_IO] = client
-      env[RACK_INPUT] = 0 == hp.content_length ?
-               NULL_IO : IC.new(ts = TeeSocket.new(client), hp)
-      env[REMOTE_ADDR] = remote_addr
-      status, headers, body = app.call(env.update(RACK_DEFAULTS))
-
-      if 100 == status.to_i
-        client.write(EXPECT_100_RESPONSE)
-        env.delete(HTTP_EXPECT)
-        status, headers, body = app.call(env)
-      end
-
-      if hp.headers?
-        headers = HH.new(headers)
-        range = make_range!(env, status, headers) and status = range.shift
-        headers[CONNECTION] = (alive = hp.next?) ? KEEP_ALIVE : CLOSE
-        client.write(response_header(status, headers))
-        alive && ts and buf << ts.leftover
-      end
-      write_body(client, body, range)
-    end while alive
-  rescue Revactor::TCP::ReadError
-  rescue => e
-    Rainbows::Error.write(io, e)
-  ensure
-    client.close
-  end
 
   # runs inside each forked worker, this sits around and waits
   # for connections and doesn't die until the parent dies (or is
   # given a INT, QUIT, or TERM signal)
   def worker_loop(worker) #:nodoc:
+    Client.setup
     init_worker_process(worker)
-    require 'rainbows/revactor/body'
-    self.class.__send__(:include, Rainbows::Revactor::Body)
-    self.class.const_set(:IC, Unicorn::HttpRequest.input_class)
-    RD_ARGS[:timeout] = G.kato if G.kato > 0
     nr = 0
     limit = worker_connections
     actor_exit = Case[:exit, Actor, Object]
@@ -114,7 +55,7 @@ module Rainbows::Revactor
             f.when(actor_exit) { nr -= 1 }
             f.when(accept) do |_, _, s|
               nr += 1
-              Actor.spawn_link(s) { |c| process_client(c) }
+              Actor.spawn_link(s) { |c| Client.new(c).process_loop }
             end
           end
         rescue => e