Class: Elements::ElementsClient
- Inherits:
-
Object
- Object
- Elements::ElementsClient
- Includes:
- Logging
- Defined in:
- lib/elements/elements_client.rb
Overview
ElementsClient executes HTTP requests against the Elements API, converts the response into a resource object or an error object accordingly.
Defined Under Namespace
Classes: ThreadContext
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
Class Method Summary collapse
- .active_client ⇒ Object
- .current_thread_context ⇒ Object
- .default_client ⇒ Object
- .should_retry?(error, attempts, config) ⇒ Boolean
- .sleep_duration(attempts, config) ⇒ Object
Instance Method Summary collapse
- #execute_request(method, path, params: {}, headers: {}, opts: {}) ⇒ Object
-
#initialize(config_arg = {}) ⇒ ElementsClient
constructor
A new instance of ElementsClient.
Methods included from Logging
#log_debug, #log_error, #log_info, #log_warn
Constructor Details
#initialize(config_arg = {}) ⇒ ElementsClient
Returns a new instance of ElementsClient.
11 12 13 |
# File 'lib/elements/elements_client.rb', line 11 def initialize(config_arg = {}) @config = Elements.config.reverse_duplicate_merge(config_arg) end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
9 10 11 |
# File 'lib/elements/elements_client.rb', line 9 def config @config end |
Class Method Details
.active_client ⇒ Object
19 20 21 |
# File 'lib/elements/elements_client.rb', line 19 def self.active_client current_thread_context.active_client || default_client end |
.current_thread_context ⇒ Object
15 16 17 |
# File 'lib/elements/elements_client.rb', line 15 def self.current_thread_context Thread.current[:elements_client__internal_use_only] ||= ThreadContext.new end |
.default_client ⇒ Object
23 24 25 |
# File 'lib/elements/elements_client.rb', line 23 def self.default_client current_thread_context.default_client ||= ElementsClient.new end |
.should_retry?(error, attempts, config) ⇒ Boolean
76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/elements/elements_client.rb', line 76 def self.should_retry?(error, attempts, config) return false if attempts >= config.max_network_retries # retry if it is a connection issue return true if error.is_a?(Elements::APIConnectionError) # retry if it is a conflict, e.g., record not saved return true if error.is_a?(Elements::ElementsError) && error.http_status == 409 # retry if service is temporarily unavailable return true if error.is_a?(Elements::ElementsError) && error.http_status == 503 false end |
.sleep_duration(attempts, config) ⇒ Object
88 89 90 91 92 93 94 |
# File 'lib/elements/elements_client.rb', line 88 def self.sleep_duration(attempts, config) duration = config.min_network_retry_delay * (2**(attempts - 1)) # adding jitter, https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/ duration = rand(duration) duration = [config.min_network_retry_delay, duration].max [config.max_network_retry_delay, duration].min end |
Instance Method Details
#execute_request(method, path, params: {}, headers: {}, opts: {}) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/elements/elements_client.rb', line 27 def execute_request(method, path, params: {}, headers: {}, opts: {}) api_base = opts[:api_base] || config.api_base api_key = opts[:api_key] || config.api_key body_params, query_params = if %i[get head delete].include?(method) [nil, params] else [params, nil] end query_params, path = merge_query_params(query_params, path) query = encode_query_params(query_params) headers = request_headers(api_key, method).update(headers) body = body_params ? JSON.generate(body_params) : nil url = api_url(path, query, api_base) context = { method: method, path: path, query: query, body: body_params, idempotency_key: headers['Idempotency-Key'] } log_request(context) resp = with_retries do execute_request_with_rescues(method, url, headers, body, context) end log_response(context, resp) resp end |