diff options
Diffstat (limited to 'lib/rainbows/event_machine_defer.rb')
-rw-r--r-- | lib/rainbows/event_machine_defer.rb | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/rainbows/event_machine_defer.rb b/lib/rainbows/event_machine_defer.rb new file mode 100644 index 0000000..4625ab8 --- /dev/null +++ b/lib/rainbows/event_machine_defer.rb @@ -0,0 +1,54 @@ +require 'rainbows/event_machine' + +module Rainbows + module EventMachineDefer + include Rainbows::EventMachine + + class Client < Rainbows::EventMachine::Client + undef_method :app_call + + def defer_op + @env[RACK_INPUT] = @input + @env[REMOTE_ADDR] = @remote_addr + @env[ASYNC_CALLBACK] = method(:response_write) + catch(:async) { APP.call(@env.update(RACK_DEFAULTS)) } + rescue => e + handle_error(e) + nil + end + + def defer_callback(response) + # too tricky to support pipelining with :async since the + # second (pipelined) request could be a stuck behind a + # long-running async response + (response.nil? || -1 == response.first) and return @state = :close + + resume + + alive = @hp.keepalive? && G.alive + out = [ alive ? CONN_ALIVE : CONN_CLOSE ] if @hp.headers? + response_write(response, out, alive) + if alive + @env.clear + @hp.reset + @state = :headers + if @hp.headers(@env, @buf) + EM.next_tick(method(:app_call)) + else + set_comm_inactivity_timeout(G.kato) + end + else + quit + end + end + + def app_call + pause + set_comm_inactivity_timeout(0) + # defer_callback(defer_op) + EM.defer(method(:defer_op), method(:defer_callback)) + end + end + + end +end |