class Faraday::Adapter::EMHttp
EventMachine adapter is useful for either asynchronous requests when in EM reactor loop or for making parallel requests in synchronous code.
Public Class Methods
setup_parallel_manager(options = nil)
click to toggle source
# File lib/faraday/adapter/em_http.rb, line 84 def self.setup_parallel_manager(options = nil) Manager.new end
Public Instance Methods
call(env)
click to toggle source
Calls superclass method
Faraday::Adapter#call
# File lib/faraday/adapter/em_http.rb, line 88 def call(env) super perform_request env @app.call env end
create_request(env)
click to toggle source
# File lib/faraday/adapter/em_http.rb, line 153 def create_request(env) EventMachine::HttpRequest.new(env[:url], connection_config(env).merge(@connection_options)) end
error_message(client)
click to toggle source
# File lib/faraday/adapter/em_http.rb, line 157 def error_message(client) client.error or "request failed" end
parallel?(env)
click to toggle source
# File lib/faraday/adapter/em_http.rb, line 175 def parallel?(env) !!env[:parallel_manager] end
perform_request(env)
click to toggle source
# File lib/faraday/adapter/em_http.rb, line 94 def perform_request(env) if parallel?(env) manager = env[:parallel_manager] manager.add { perform_single_request(env). callback { env[:response].finish(env) } } else unless EventMachine.reactor_running? error = nil # start EM, block until request is completed EventMachine.run do perform_single_request(env). callback { EventMachine.stop }. errback { |client| error = error_message(client) EventMachine.stop } end raise_error(error) if error else # EM is running: instruct upstream that this is an async request env[:parallel_manager] = true perform_single_request(env). callback { env[:response].finish(env) }. errback { # TODO: no way to communicate the error in async mode raise NotImplementedError } end end rescue EventMachine::Connectify::CONNECTError => err if err.message.include?("Proxy Authentication Required") raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "} else raise Error::ConnectionFailed, err end rescue => err if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err raise Faraday::SSLError, err else raise end end
perform_single_request(env)
click to toggle source
TODO: reuse the connection to support pipelining
# File lib/faraday/adapter/em_http.rb, line 140 def perform_single_request(env) req = create_request(env) req.setup_request(env[:method], request_config(env)).callback { |client| status = client.response_header.status reason = client.response_header.http_reason save_response(env, status, client.response, nil, reason) do |resp_headers| client.response_header.each do |name, value| resp_headers[name.to_sym] = value end end } end
raise_error(msg)
click to toggle source
# File lib/faraday/adapter/em_http.rb, line 161 def raise_error(msg) errklass = Faraday::Error::ClientError if msg == Errno::ETIMEDOUT errklass = Faraday::Error::TimeoutError msg = "request timed out" elsif msg == Errno::ECONNREFUSED errklass = Faraday::Error::ConnectionFailed msg = "connection refused" elsif msg == "connection closed by server" errklass = Faraday::Error::ConnectionFailed end raise errklass, msg end