Created
March 6, 2011 18:05
-
-
Save joshk/857465 to your computer and use it in GitHub Desktop.
em deferrable faraday adapter
This file contains 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
module Faraday | |
class Adapter | |
class EMHttpRequest < Faraday::Adapter | |
self.supports_parallel_requests = true | |
def self.setup_parallel_manager(options = {}) | |
EMParallelManager.new | |
end | |
class EMParallelManager | |
def run; true; end | |
end | |
begin | |
require 'em' | |
require 'em-http' | |
rescue LoadError, NameError => e | |
self.load_error = e | |
end | |
class Header | |
include Net::HTTPHeader | |
def initialize response | |
@header = {} | |
response.response_header.each do |key, value| | |
case key | |
when "CONTENT_TYPE"; self.content_type = value | |
when "CONTENT_LENGTH"; self.content_length = value | |
else; self[key] = value | |
end | |
end | |
end | |
end | |
def call(env) | |
super | |
http_async = EventMachine::HttpRequest.new(URI::parse(env[:url].to_s)) | |
options = setup_request_options(env) | |
http = http_async.setup_request(env[:method].to_s.downcase.to_sym, options) | |
http.callback do | |
env.update({ | |
:body => http.response, | |
:status => http.response_header.status.to_i, | |
:response_headers => Header.new(http) | |
}) | |
env[:response].finish(env) | |
end | |
http.errback do | |
raise Error::ConnectionFailed.new(Errno::ECONNREFUSED) | |
end | |
@app.call(env) | |
end | |
def setup_request_options(env) | |
options = { :head => env[:request_headers] } | |
options[:ssl] = env[:ssl] if env[:ssl] | |
if env[:body] | |
if env[:body].respond_to? :read | |
options[:body] = env[:body].read | |
else | |
options[:body] = env[:body] | |
end | |
end | |
if req = env[:request] | |
if proxy = req[:proxy] | |
uri = Addressable::URI.parse(proxy[:uri]) | |
options[:proxy] = { | |
:host => uri.host, | |
:port => uri.port | |
} | |
if proxy[:username] && proxy[:password] | |
options[:proxy][:authorization] = [proxy[:username], proxy[:password]] | |
end | |
end | |
# only one timeout currently supported by em http request | |
if req[:timeout] or req[:open_timeout] | |
options[:timeout] = [req[:timeout] || 0, req[:open_timeout] || 0].max | |
end | |
end | |
options | |
end | |
end | |
end | |
end |
This file contains 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 'eventmachine' | |
require 'em-http' | |
require 'faraday' | |
require 'faraday/adapter/em_http_request' | |
parallel_manager = Faraday::Adapter::EMHttpRequest.setup_parallel_manager | |
c = Faraday.new(:url => 'http://google.com', :parallel => parallel_manager) do |builder| | |
builder.adapter :EMHttpRequest | |
end | |
EM.run do | |
c.get('/') | |
puts 'wait for it all to run' | |
EM.add_timer(3) { EM.stop } | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
No, no.. Given what you're going for (fire and forget), I think it makes sense.
My only worry is that if at some point you will want to synchronize to see what happens to all the requests (or wait for them to finish), then I think you'll have to introduce some other deferrable into the mix (which is multi is all about - and its very simple). Take a look at that code and you'll see what I mean.
Glad you got it working!