Class: Faraday::Adapter::EMHttp

Inherits:
Faraday::Adapter show all
Includes:
Options
Defined in:
lib/faraday/adapter/em_http.rb

Overview

EventMachine adapter is useful for either asynchronous requests when in EM reactor loop or for making parallel requests in synchronous code.

Defined Under Namespace

Modules: Options Classes: Manager

Constant Summary

Constants inherited from Faraday::Adapter

CONTENT_LENGTH

Instance Attribute Summary

Attributes included from Parallelism

#supports_parallel

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Options

#configure_compression, #configure_proxy, #configure_timeout, #connection_config, #read_body, #request_config, #request_options

Methods inherited from Faraday::Adapter

#save_response

Methods included from Faraday::AutoloadHelper

#all_loaded_constants, #autoload_all, #load_autoloaded_constants

Methods included from MiddlewareRegistry

#lookup_middleware, #register_middleware

Methods included from Parallelism

#inherited, #supports_parallel?

Methods inherited from Middleware

dependency, inherited, #initialize, loaded?, new

Constructor Details

This class inherits a constructor from Faraday::Middleware

Class Method Details

.setup_parallel_manager(options = nil) ⇒ Object



64
65
66
# File 'lib/faraday/adapter/em_http.rb', line 64

def self.setup_parallel_manager(options = nil)
  Manager.new
end

Instance Method Details

#call(env) ⇒ Object



68
69
70
71
72
# File 'lib/faraday/adapter/em_http.rb', line 68

def call(env)
  super
  perform_request env
  @app.call env
end

#error_message(client) ⇒ Object



125
126
127
# File 'lib/faraday/adapter/em_http.rb', line 125

def error_message(client)
  client.error or "request failed"
end

#parallel?(env) ⇒ Boolean

Returns:

  • (Boolean)


143
144
145
# File 'lib/faraday/adapter/em_http.rb', line 143

def parallel?(env)
  !!env[:parallel_manager]
end

#perform_request(env) ⇒ Object



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
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/faraday/adapter/em_http.rb', line 74

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
end

#perform_single_request(env) ⇒ Object

TODO: reuse the connection to support pipelining



114
115
116
117
118
119
120
121
122
123
# File 'lib/faraday/adapter/em_http.rb', line 114

def perform_single_request(env)
  req = EventMachine::HttpRequest.new(env[:url], connection_config(env))
  req.setup_request(env[:method], request_config(env)).callback { |client|
    save_response(env, client.response_header.status, client.response) do |resp_headers|
      client.response_header.each do |name, value|
        resp_headers[name.to_sym] = value
      end
    end
  }
end

#raise_error(msg) ⇒ Object

Raises:

  • (errklass)


129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/faraday/adapter/em_http.rb', line 129

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