Class: Nombaone::Internal::HTTPClient Private
- Inherits:
-
Object
- Object
- Nombaone::Internal::HTTPClient
- Defined in:
- lib/nombaone/internal/http_client.rb,
sig/nombaone/internal.rbs
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
Executes one logical API call: builds the request, runs the retry loop, parses the response envelope, and returns a Result or raises a typed error.
Money-safety invariants enforced here and nowhere else:
- The
Idempotency-Keyfor a POST is computed once, before the retry loop, so every automatic retry replays the same logical operation instead of creating a new one. - A caller-initiated cancellation is never retried; only timeouts, connection failures, 408/429/5xx, and our own in-flight idempotency conflict are.
Constant Summary collapse
- API_PREFIX =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
The version prefix is applied here, at exactly one place — never in a resource path.
"/v1"- RETRYABLE_STATUSES =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Statuses retried unconditionally (409 is retried only for
IDEMPOTENCY_IN_PROGRESS, handled in #retryable?). [408, 429, 500, 502, 503, 504].freeze
Instance Method Summary collapse
-
#initialize(api_key:, base_url:, timeout:, max_retries:, connection:, default_headers: nil, sleeper: nil) ⇒ HTTPClient
constructor
private
A new instance of HTTPClient.
- #request(method:, path:, query: nil, body: nil, options: nil) ⇒ Nombaone::Internal::Result private
Constructor Details
#initialize(api_key:, base_url:, timeout:, max_retries:, connection:, default_headers: nil, sleeper: nil) ⇒ HTTPClient
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of HTTPClient.
93 94 95 96 97 98 99 100 101 102 |
# File 'lib/nombaone/internal/http_client.rb', line 93 def initialize(api_key:, base_url:, timeout:, max_retries:, connection:, default_headers: nil, sleeper: nil) @api_key = api_key @base_url = base_url @timeout = timeout @max_retries = max_retries @connection = connection @default_headers = default_headers @sleeper = sleeper || ->(seconds) { sleep(seconds) } end |
Instance Method Details
#request(method:, path:, query: nil, body: nil, options: nil) ⇒ Nombaone::Internal::Result
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/nombaone/internal/http_client.rb', line 111 def request(method:, path:, query: nil, body: nil, options: nil) ||= {} timeout = [:timeout] || @timeout max_retries = [[:max_retries] || @max_retries, 0].max cancel_when = [:cancel_when] url = build_url(path, query) headers = build_headers(method, body, ) payload = body.nil? ? nil : JSON.generate(body) attempt = 0 loop do raise_if_canceled(cancel_when) begin response = @connection.execute( method: method, url: url, headers: headers, body: payload, timeout: timeout, ) rescue Nombaone::TimeoutError, Nombaone::ConnectionError => e raise e if attempt >= max_retries wait(Util.backoff_seconds(attempt)) attempt += 1 next end parsed = parse_json(response.body) return build_result(response, parsed) if success_status?(response.status) error = APIError.from_response(response.status, parsed, response.headers) raise error unless attempt < max_retries && retryable?(response.status, error) retry_after = Util.retry_after_seconds(response.headers["retry-after"]) wait(retry_after || Util.backoff_seconds(attempt)) attempt += 1 end end |