Class: GetFluxly::Http

Inherits:
Object
  • Object
show all
Defined in:
lib/getfluxly/http.rb

Overview

Thin Net::HTTP wrapper. Retries 408 / 425 / 429 / 5xx with exponential backoff and +/- 25% jitter. Honors Retry-After when present.

Constant Summary collapse

SDK_LIBRARY =
"gflux-ruby/#{GetFluxly::VERSION}".freeze
RETRY_STATUSES =
[408, 425, 429].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(token:, api_host:, timeout:, max_retries:) ⇒ Http

Returns a new instance of Http.



16
17
18
19
20
21
# File 'lib/getfluxly/http.rb', line 16

def initialize(token:, api_host:, timeout:, max_retries:)
  @token = token
  @api_host = api_host.sub(%r{/+\z}, "")
  @timeout = timeout
  @max_retries = max_retries
end

Class Method Details

.generate_idempotency_keyObject



53
54
55
# File 'lib/getfluxly/http.rb', line 53

def self.generate_idempotency_key
  SecureRandom.uuid
end

Instance Method Details

#post(path_or_url, body, idempotency_key: nil, request_id: nil) ⇒ Object



23
24
25
26
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
# File 'lib/getfluxly/http.rb', line 23

def post(path_or_url, body, idempotency_key: nil, request_id: nil)
  uri = absolute_uri(path_or_url)
  payload = JSON.dump(body)

  headers = {
    "Content-Type" => "application/json",
    "Authorization" => "Bearer #{@token}",
    "X-GFlux-SDK" => SDK_LIBRARY
  }
  headers["X-Idempotency-Key"] = idempotency_key if idempotency_key
  headers["X-Request-Id"] = request_id if request_id

  attempt = 0
  loop do
    response = perform(uri, payload, headers)
    parsed = parse_body(response)
    status = response.code.to_i

    return parsed if status.between?(200, 299)

    if should_retry?(status) && attempt < @max_retries
      attempt += 1
      sleep(retry_after_seconds(response["Retry-After"], attempt))
      next
    end

    raise build_error(response, parsed)
  end
end