From 8e9672d13ed07cc262894b4770c0b9c016359712 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 26 Oct 2009 01:57:56 -0700 Subject: eventmachine: add async_sinatra support This is should be compatible with how the Thin webserver provides async callback support. See http://github.com/raggi/async_sinatra for the details --- lib/rainbows/event_machine.rb | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'lib/rainbows/event_machine.rb') diff --git a/lib/rainbows/event_machine.rb b/lib/rainbows/event_machine.rb index 678a771..7009fce 100644 --- a/lib/rainbows/event_machine.rb +++ b/lib/rainbows/event_machine.rb @@ -31,6 +31,9 @@ module Rainbows include Rainbows::EvCore G = Rainbows::G + # Apps may return this Rack response: AsyncResponse = [ -1, {}, [] ] + ASYNC_CALLBACK = 'async.callback'.freeze + def initialize(io) @_io = io end @@ -48,7 +51,15 @@ module Rainbows (@env[RACK_INPUT] = @input).rewind alive = @hp.keepalive? @env[REMOTE_ADDR] = @remote_addr - response = G.app.call(@env.update(RACK_DEFAULTS)) + @env[ASYNC_CALLBACK] = @response_write ||= method(:response_write) + + response = catch(:async) { G.app.call(@env.update(RACK_DEFAULTS)) } + + # 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 + alive &&= G.alive out = [ alive ? CONN_ALIVE : CONN_CLOSE ] if @hp.headers? response_write(response, out, alive) @@ -64,7 +75,7 @@ module Rainbows end while true end - def response_write(response, out, alive) + def response_write(response, out = [], alive = false) body = response.last unless body.respond_to?(:to_path) HttpResponse.write(self, response, out) -- cgit v1.2.3-24-ge0c7