diff options
author | Eric Wong <normalperson@yhbt.net> | 2010-05-03 17:56:00 -0700 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2010-05-03 17:56:00 -0700 |
commit | de3bcfe3ba9402bd510f7414df1763b6b99dae47 (patch) | |
tree | 180526ea73118ed9e3b0cc606684288991875b72 /lib/rainbows/revactor.rb | |
parent | 54cae80e543a6f4ca6456fe07b88aba867d215a6 (diff) | |
download | rainbows-de3bcfe3ba9402bd510f7414df1763b6b99dae47.tar.gz |
WAvoid mucking with Unicorn::TeeInput, since other apps may depend on that class, so we subclass it as Rainbows::TeeInput and modify as necessary in worker processes. For Revactor, remove the special-cased Rainbows::Revactor::TeeInput class and instead emulate readpartial for Revactor sockets instead.
Diffstat (limited to 'lib/rainbows/revactor.rb')
-rw-r--r-- | lib/rainbows/revactor.rb | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/lib/rainbows/revactor.rb b/lib/rainbows/revactor.rb index ed08f2c..21fa72f 100644 --- a/lib/rainbows/revactor.rb +++ b/lib/rainbows/revactor.rb @@ -21,8 +21,6 @@ module Rainbows # concurrency features this model provides. module Revactor - require 'rainbows/revactor/tee_input' - RD_ARGS = {} include Base @@ -52,7 +50,7 @@ module Rainbows env[Const::CLIENT_IO] = client env[Const::RACK_INPUT] = 0 == hp.content_length ? HttpRequest::NULL_IO : - Rainbows::Revactor::TeeInput.new(client, env, hp, buf) + TeeInput.new(PartialSocket.new(client), env, hp, buf) env[Const::REMOTE_ADDR] = remote_addr response = app.call(env.update(RACK_DEFAULTS)) @@ -137,5 +135,40 @@ module Rainbows end end + # Revactor Sockets do not implement readpartial, so we emulate just + # enough to avoid mucking with TeeInput internals. Fortunately + # this code is not heavily used so we can usually avoid the overhead + # of adding a userspace buffer. + class PartialSocket < Struct.new(:socket, :rbuf) + def initialize(socket) + # IO::Buffer is used internally by Rev which Revactor is based on + # so we'll always have it available + super(socket, IO::Buffer.new) + end + + # Revactor socket reads always return an unspecified amount, + # sometimes too much + def readpartial(length, dst = "") + # always check and return from the userspace buffer first + rbuf.size > 0 and return dst.replace(rbuf.read(length)) + + # read off the socket since there was nothing in rbuf + tmp = socket.read + + # we didn't read too much, good, just return it straight back + # to avoid needlessly wasting memory bandwidth + tmp.size <= length and return dst.replace(tmp) + + # ugh, read returned too much, copy + reread to avoid slicing + rbuf << tmp[length, tmp.size] + dst.replace(tmp[0, length]) + end + + # just proxy any remaining methods TeeInput may use + def close + socket.close + end + end + end end |