about summary refs log tree commit homepage
path: root/lib/rainbows/fiber
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rainbows/fiber')
-rw-r--r--lib/rainbows/fiber/base.rb32
-rw-r--r--lib/rainbows/fiber/body.rb36
-rw-r--r--lib/rainbows/fiber/rev.rb3
3 files changed, 43 insertions, 28 deletions
diff --git a/lib/rainbows/fiber/base.rb b/lib/rainbows/fiber/base.rb
index 7e39441..9ac3b72 100644
--- a/lib/rainbows/fiber/base.rb
+++ b/lib/rainbows/fiber/base.rb
@@ -72,33 +72,6 @@ module Rainbows
         max.nil? || max > (now + 1) ? 1 : max - now
       end
 
-      # TODO: IO.splice under Linux
-      alias write_body_stream write_body_each
-
-      # the sendfile 1.0.0+ gem includes IO#sendfile_nonblock
-      if ::IO.method_defined?(:sendfile_nonblock)
-        def write_body_path(client, body)
-          file = Rainbows.body_to_io(body)
-          if file.stat.file?
-            sock, off = client.to_io, 0
-            begin
-              off += sock.sendfile_nonblock(file, off, 0x10000)
-            rescue Errno::EAGAIN
-              client.wait_writable
-            rescue EOFError
-              break
-            rescue => e
-              Rainbows::Error.app(e)
-              break
-            end while true
-          else
-            write_body_stream(client, body)
-          end
-        end
-      else
-        alias write_body write_body_each
-      end
-
       def wait_headers_readable(client)
         io = client.to_io
         expire = nil
@@ -120,6 +93,11 @@ module Rainbows
         ZZ.delete(client.f)
       end
 
+      def self.setup(klass, app)
+        require 'rainbows/fiber/body'
+        klass.__send__(:include, Rainbows::Fiber::Body)
+        self.const_set(:APP, app)
+      end
     end
   end
 end
diff --git a/lib/rainbows/fiber/body.rb b/lib/rainbows/fiber/body.rb
new file mode 100644
index 0000000..cd6c55c
--- /dev/null
+++ b/lib/rainbows/fiber/body.rb
@@ -0,0 +1,36 @@
+# -*- encoding: binary -*-
+# non-portable body handling for Fiber-based concurrency goes here
+# this module is required and included in worker processes only
+# this is meant to be included _after_ Rainbows::HttpResponse::Body
+module Rainbows::Fiber::Body # :nodoc:
+
+  # TODO non-blocking splice(2) under Linux
+  ALIASES = {
+    :write_body_stream => :write_body_each
+  }
+
+  # the sendfile 1.0.0+ gem includes IO#sendfile_nonblock
+  if ::IO.method_defined?(:sendfile_nonblock)
+    def write_body_file(client, body)
+      sock, off = client.to_io, 0
+      begin
+        off += sock.sendfile_nonblock(body, off, 0x10000)
+      rescue Errno::EAGAIN
+        client.wait_writable
+      rescue EOFError
+        break
+      rescue => e
+        Rainbows::Error.app(e)
+        break
+      end while true
+    end
+  else
+    ALIASES[:write_body] = :write_body_each
+  end
+
+  def self.included(klass)
+    ALIASES.each do |new_method, orig_method|
+      klass.__send__(:alias_method, new_method, orig_method)
+    end
+  end
+end
diff --git a/lib/rainbows/fiber/rev.rb b/lib/rainbows/fiber/rev.rb
index b8ec56b..2e8f076 100644
--- a/lib/rainbows/fiber/rev.rb
+++ b/lib/rainbows/fiber/rev.rb
@@ -52,6 +52,7 @@ module Rainbows::Fiber
       include Unicorn
       include Rainbows
       include Rainbows::Const
+      include Rainbows::HttpResponse
       FIO = Rainbows::Fiber::IO
 
       def to_io
@@ -99,7 +100,7 @@ module Rainbows::Fiber
 
           alive = hp.keepalive? && G.alive
           out = [ alive ? CONN_ALIVE : CONN_CLOSE ] if hp.headers?
-          HttpResponse.write(client, response, out)
+          write_response(client, response, out)
         end while alive and hp.reset.nil? and env.clear
       rescue => e
         Error.write(io, e)