public
Last active

  • Download Gist
async-camping.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
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

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.