Skip to content

@judofyr /async-camping.rb
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
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
Something went wrong with that request. Please try again.