refactor response sendfile body handling for easier debugging
[rainbows.git] / lib / rainbows / fiber / body.rb
blob1d7d3252f0a318bb2a3fa6e90621ee880ad4d68d
1 # -*- encoding: binary -*-
2 # :enddoc:
3 # non-portable body handling for Fiber-based concurrency goes here
4 # this module is required and included in worker processes only
5 # this is meant to be included _after_ Rainbows::Response::Body
6 module Rainbows::Fiber::Body # :nodoc:
8   # TODO non-blocking splice(2) under Linux
9   ALIASES = {
10     :write_body_stream => :write_body_each
11   }
13   # the sendfile 1.0.0+ gem includes IO#sendfile_nonblock
14   if IO.method_defined?(:sendfile_nonblock)
15     def write_body_file_sendfile_fiber(client, body, range)
16       sock, n, body = client.to_io, nil, body_to_io(body)
17       offset, count = range ? range : [ 0, body.stat.size ]
18       begin
19         offset += (n = sock.sendfile_nonblock(body, offset, count))
20       rescue Errno::EAGAIN
21         client.kgio_wait_writable
22         retry
23       rescue EOFError
24         break
25       end while (count -= n) > 0
26       ensure
27         close_if_private(body)
28     end
29     ALIASES[:write_body_file] = :write_body_file_sendfile_fiber
30   else
31     ALIASES[:write_body] = :write_body_each
32   end
34   def self.included(klass)
35     ALIASES.each do |new_method, orig_method|
36       klass.__send__(:alias_method, new_method, orig_method)
37     end
38   end
39 end