diff options
author | Eric Wong <normalperson@yhbt.net> | 2010-12-30 08:33:15 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2011-01-04 16:37:42 -0800 |
commit | e21939d776673b2f8887adf7a5c64812b7d2e98e (patch) | |
tree | 48aa3a71201e770758bd09b325c3f2704411af7f /lib/rainbows/revactor/client/methods.rb | |
parent | 4a76da1833922c74e147be5def9bfe04fd0c16a2 (diff) | |
download | rainbows-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/client/methods.rb')
-rw-r--r-- | lib/rainbows/revactor/client/methods.rb | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/lib/rainbows/revactor/client/methods.rb b/lib/rainbows/revactor/client/methods.rb new file mode 100644 index 0000000..e9b39a3 --- /dev/null +++ b/lib/rainbows/revactor/client/methods.rb @@ -0,0 +1,45 @@ +# -*- encoding: binary -*- +# :enddoc: +module Rainbows::Revactor::Client::Methods + if IO.method_defined?(:sendfile_nonblock) + def write_body_file(body, range) + body, client = body_to_io(body), @client + sock = @client.instance_variable_get(:@_io) + pfx = Revactor::TCP::Socket === client ? :tcp : :unix + write_complete = T[:"#{pfx}_write_complete", client] + closed = T[:"#{pfx}_closed", client] + offset, count = range ? range : [ 0, body.stat.size ] + begin + offset += (n = sock.sendfile_nonblock(body, offset, count)) + rescue Errno::EAGAIN + # The @_write_buffer is empty at this point, trigger the + # on_readable method which in turn triggers on_write_complete + # even though nothing was written + client.controller = Actor.current + client.__send__(:enable_write_watcher) + Actor.receive do |filter| + filter.when(write_complete) {} + filter.when(closed) { raise Errno::EPIPE } + end + retry + rescue EOFError + break + end while (count -= n) > 0 + ensure + close_if_private(body) + end + end + + def handle_error(e) + Revactor::TCP::ReadError === e or super + end + + def write_response(status, headers, body, alive) + super(status, headers, body, alive) + alive && @ts and @hp.buf << @ts.leftover + end + + def self.included(klass) + klass.__send__ :alias_method, :write_body_stream, :write_body_each + end +end |