How to use deferred objects in thin-powered Sinatra app (without using async_sinatra)
require 'rubygems'
require './app.rb'
run App
require 'logger'
require 'sinatra'
require 'rack/fiber_pool'
require 'em-synchrony'
require 'em-http-request'
require 'em-synchrony/em-http'
$error_Handler = lambda {|env, exception| [503,{}, "fiber error handler #{exception}"] }
class DeferrableResponse
def initialize deferrable
@callback = proc { |*args| args }
@errback = proc { |*args| args }
@deferrable = deferrable
end
def callback &block
@callback = block
end
def errback &block
@errback = block
end
def respond
current_fiber = Fiber.current
@deferrable.callback { |*args| current_fiber.resume @callback.call(*args) }
@deferrable.errback { |*args| current_fiber.resume @errback.call(*args) }
Fiber.yield
end
end
class App < Sinatra::Base
enable :logging
use Rack::FiberPool, size: 10, rescue_exception: $error_Handler
before do
logger.info env['REQUEST_URI']
end
get '/em' do # regular even machine stuff, shouldn't block
logger.info "ello"
conn = EM::HttpRequest.new('http://coffeesounds.com')
response = DeferrableResponse.new conn.aget
response.callback do|a|
logger.info "Success!"
status 201
body "em callback: #{a.response.length}"
end
response.errback do |a|
logger.error "CB error #{err}"
status 510
body "FAIL FAIL"
end
response.respond
end
get '/ems' do
# this is already using monkey patched EM::HTTP
r = EM::HttpRequest.new('http://coffeesounds.com').get
status 201
body "Body: #{r.response.length}"
end
end
Rack fiber pool + EM deferrables + em-synchrony is a nice idea.
While em-synchrony powered libraries work out of the box, objects which are deferrables don't play that nicely.
Lets use fibers then (just like em-synchrony, but with less transparency)!
GEM
remote: http://rubygems.org/
specs:
addressable (2.3.2)
coderay (1.0.8)
cookiejar (0.3.0)
daemons (1.1.9)
em-http-request (1.0.3)
addressable (>= 2.2.3)
cookiejar
em-socksify
eventmachine (>= 1.0.0.beta.4)
http_parser.rb (>= 0.5.3)
em-socksify (0.2.1)
eventmachine (>= 1.0.0.beta.4)
em-synchrony (1.0.2)
eventmachine (>= 1.0.0.beta.1)
eventmachine (1.0.0)
http_parser.rb (0.5.3)
method_source (0.8.1)
pry (0.9.10)
coderay (~> 1.0.5)
method_source (~> 0.8)
slop (~> 3.3.1)
rack (1.4.1)
rack-fiber_pool (0.9.2)
rack-protection (1.3.2)
rack
sinatra (1.3.3)
rack (~> 1.3, >= 1.3.6)
rack-protection (~> 1.2)
tilt (~> 1.3, >= 1.3.3)
slop (3.3.3)
thin (1.5.0)
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
rack (>= 1.0.0)
tilt (1.3.3)
PLATFORMS
ruby
DEPENDENCIES
em-http-request
em-synchrony
pry
rack-fiber_pool
sinatra
thin
source :rubygems
gem 'sinatra'
gem 'rack-fiber_pool'
gem 'thin'
gem 'em-synchrony'
gem 'em-http-request'
gem 'pry', require: 'pry'