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_ssl, #configure_timeout, #connection_config, #read_body, #request_config, #request_options

Methods inherited from Faraday::Adapter

#prepend_proxy_auth_string, #save_response

Methods included from Parallelism

#inherited, #supports_parallel?

Methods included from MiddlewareRegistry

#lookup_middleware, #register_middleware

Methods included from Faraday::AutoloadHelper

#all_loaded_constants, #autoload_all, #load_autoloaded_constants

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


76
77
78
# File 'lib/faraday/adapter/em_http.rb', line 76

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

Instance Method Details

#call(env) ⇒ Object


80
81
82
83
84
# File 'lib/faraday/adapter/em_http.rb', line 80

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

#error_message(client) ⇒ Object


131
132
133
# File 'lib/faraday/adapter/em_http.rb', line 131

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

#parallel?(env) ⇒ Boolean


147
148
149
# File 'lib/faraday/adapter/em_http.rb', line 147

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

#perform_request(env) ⇒ Object


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
112
113
114
115
116
117
# File 'lib/faraday/adapter/em_http.rb', line 86

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
end

#perform_single_request(env) ⇒ Object

TODO: reuse the connection to support pipelining


120
121
122
123
124
125
126
127
128
129
# File 'lib/faraday/adapter/em_http.rb', line 120

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)

135
136
137
138
139
140
141
142
143
144
145
# File 'lib/faraday/adapter/em_http.rb', line 135

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"
  end
  raise errklass, msg
end