Created
September 4, 2011 11:34
-
-
Save judofyr/1192720 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'camping' | |
Camping.goes :Async | |
module Async | |
def service(*a) | |
return super unless respond_to?(:async?) | |
EM.next_tick do | |
send(@method, *a) | |
end | |
throw :async | |
end | |
end | |
module Async::Helpers | |
class DeferrableBody | |
include EventMachine::Deferrable | |
def call(body) | |
body.each do |chunk| | |
@body_callback.call(chunk) | |
end | |
end | |
def each &blk | |
@body_callback = blk | |
end | |
end | |
ASYNC_CALLBACK = 'async.callback'.freeze | |
def stream | |
@body = [] | |
@stream ||= DeferrableBody.new | |
res = to_a | |
res[2] = @stream | |
@env[ASYNC_CALLBACK].call(res) | |
end | |
def push(body) | |
body = Array(body) unless body.respond_to?(:each) | |
@async.call(body) | |
end | |
def finish(str = "") | |
if @stream | |
@async.succeed | |
else | |
@body ||= str | |
@env[ASYNC_CALLBACK].call(to_a) | |
end | |
end | |
end | |
module Async::Controllers | |
def self.A(*r) | |
R(*r).class_eval do | |
def async?; true end | |
self | |
end | |
end | |
# Inherit from A to create async response | |
class Index < A '/' | |
def get | |
EM.add_timer(2) do | |
# Call #finish to render stuff | |
finish render(:index) | |
end | |
end | |
end | |
class Push < A '/push' | |
def get | |
# Call #stream to start a streaming response | |
stream | |
EM.add_timer(1) do | |
# Push stuff out | |
push "Hello\n" | |
end | |
EM.add_timer(2) do | |
# Push more stuff | |
push render(:index) | |
# Call #finish to close | |
finish | |
end | |
end | |
end | |
end | |
module Async::Views | |
def index | |
p 'Hello' | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment