Class: Equipoise::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/equipoise/client.rb

Constant Summary collapse

RETRYABLE_STATUSES =
[429, 500, 502, 503, 504].freeze
RETRYABLE_NETWORK_ERRORS =

Transient transport errors worth retrying.

[
  Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EHOSTUNREACH,
  Net::OpenTimeout, Net::ReadTimeout, SocketError, EOFError, IOError
].freeze
WRAPPABLE_NETWORK_ERRORS =

Other transport failures — wrapped into ConnectionError but NOT retried (a TLS cert failure won't fix itself on a retry). Listed after the retryable rescue, so the more-specific list wins.

[
  OpenSSL::SSL::SSLError, SystemCallError, Net::ProtocolError, Net::HTTPBadResponse
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = Equipoise.configuration) ⇒ Client

Returns a new instance of Client.



43
44
45
# File 'lib/equipoise/client.rb', line 43

def initialize(config = Equipoise.configuration)
  @config = config
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



41
42
43
# File 'lib/equipoise/client.rb', line 41

def config
  @config
end

Instance Method Details

#contactsObject



47
48
49
# File 'lib/equipoise/client.rb', line 47

def contacts
  @contacts ||= Contacts.new(self)
end

#custom_fieldsObject



51
52
53
# File 'lib/equipoise/client.rb', line 51

def custom_fields
  @custom_fields ||= CustomFields.new(self)
end

#request(method, path, body: nil, query: nil, headers: {}) ⇒ Object

The single request chokepoint. Returns a Response on 2xx; raises a typed ApiError (or ConnectionError) otherwise.



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/equipoise/client.rb', line 57

def request(method, path, body: nil, query: nil, headers: {})
  return null_response if config.disabled? # test-mode short-circuit — before validate! or any I/O

  config.validate!
  uri     = build_uri(path, query)
  attempt = 0

  loop do
    response =
      begin
        perform(method, uri, body, headers)
      rescue *RETRYABLE_NETWORK_ERRORS => e
        raise wrap_connection_error(e) if attempt >= config.max_retries

        attempt += 1
        backoff(attempt, nil)
        next
      rescue *WRAPPABLE_NETWORK_ERRORS => e
        raise wrap_connection_error(e)
      end

    return response if response.success?

    if retryable?(response.status) && attempt < config.max_retries
      attempt += 1
      backoff(attempt, response)
      next
    end

    raise log_error(ApiError.from_response(response))
  end
end