about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2014-03-15 03:47:39 +0000
committerEric Wong <e@80x24.org>2014-03-15 03:48:33 +0000
commitade89b5142bedbcf07f38aa062bfdbfcb8bc48d3 (patch)
treeaff261d8e56174396940ab37bad3652580193b9d
parentf6d86eff2f59f6af861deea9b4480abdfd0e5a09 (diff)
downloadyahns-ade89b5142bedbcf07f38aa062bfdbfcb8bc48d3.tar.gz
This likely makes no difference in 99% of real world situations with
fast response generation.  The only case where lack of output buffer
bypass makes a difference is when the following sequence happens:

1) a giant response cannot fit into socket buffers
2) temporary file created for buffering
3) client consumes output so we get more space in socket buffers
4) app response generation continues (streaming response)
5) we successfully write _all_ previously buffered data to socket
6) we may bypass buffering for data generated in step 4

So right now, we cannot do step 6 outside of Linux.  Instead, once an
output buffer is created; we must always write to the output buffers.
-rw-r--r--lib/yahns/wbuf.rb15
1 files changed, 14 insertions, 1 deletions
diff --git a/lib/yahns/wbuf.rb b/lib/yahns/wbuf.rb
index 293019e..21bccce 100644
--- a/lib/yahns/wbuf.rb
+++ b/lib/yahns/wbuf.rb
@@ -30,6 +30,14 @@ require_relative 'wbuf_common'
 class Yahns::Wbuf # :nodoc:
   include Yahns::WbufCommon
 
+  # TODO: Figure out why this hack is needed to pass output buffering tests.
+  # It could be a bug in our code, Ruby, the sendfile gem, or FreeBSD itself.
+  # Tested on FreeBSD fbsd 9.2-RELEASE FreeBSD 9.2-RELEASE #0 r255898
+  # We are able to use bypass mode on Linux to reduce buffering in some
+  # cases.  Without bypass mode, we must always finish writing the entire
+  # response completely before sending more data to the client.
+  bypass_ok = RUBY_PLATFORM =~ /linux/
+
   def initialize(body, persist, tmpdir)
     @tmpio = Yahns::TmpIO.new(tmpdir)
     @sf_offset = @sf_count = 0
@@ -67,7 +75,12 @@ class Yahns::Wbuf # :nodoc:
     @tmpio.rewind
     @bypass = true
     nil
-  end
+  end if bypass_ok
+
+  def wbuf_write(client, buf)
+    @sf_count += @tmpio.write(buf)
+    :wait_writable
+  end unless bypass_ok
 
   # called by last wbuf_flush
   def wbuf_close(client)