Class: Walinko::HttpClient

Inherits:
Object
  • Object
show all
Defined in:
lib/walinko/http_client.rb

Overview

Internal HTTP transport. Owns the wire format (JSON in/out, header naming), retry policy, and error mapping. The ‘Messages` resource is the only consumer.

Public methods are documented but treat anything outside ‘request` as internal — minor versions may refactor.

Defined Under Namespace

Classes: Response

Constant Summary collapse

RETRYABLE_HTTP_STATUSES =

Statuses we consider transient and retry automatically.

[429, 500, 502, 503, 504].freeze
BACKOFF_SECONDS =

Backoff curve (seconds). Index = attempt number (0 = first retry). Caps at the last entry.

[0.25, 0.75, 1.75, 3.75].freeze
MAX_RETRY_AFTER_SECONDS =

Cap on ‘Retry-After` honoring — don’t let the server make us sleep forever.

60

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ HttpClient

Returns a new instance of HttpClient.

Parameters:



41
42
43
# File 'lib/walinko/http_client.rb', line 41

def initialize(config)
  @config = config
end

Instance Attribute Details

#last_rate_limitObject (readonly)

Returns the value of attribute last_rate_limit.



38
39
40
# File 'lib/walinko/http_client.rb', line 38

def last_rate_limit
  @last_rate_limit
end

#last_request_idObject (readonly)

Returns the value of attribute last_request_id.



38
39
40
# File 'lib/walinko/http_client.rb', line 38

def last_request_id
  @last_request_id
end

Instance Method Details

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

Issues an HTTP request with the configured retry policy.

Parameters:

  • method (Symbol)

    :get / :post

  • path (String)

    e.g. “/api/v1/public/messages”

  • body (Hash, nil) (defaults to: nil)

    JSON-encoded into the request body

  • headers (Hash{String => String}) (defaults to: {})

    extra headers to merge

Returns:

Raises:



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/walinko/http_client.rb', line 53

def request(method:, path:, body: nil, headers: {})
  attempt = 0

  loop do
    result = perform(method: method, path: path, body: body, headers: headers)
    return result if result.is_a?(Response)

    # `result` is a retryable error (Exception subclass) — decide
    # whether to retry.
    attempt += 1
    raise result if attempt > @config.max_retries

    sleep_for = sleep_seconds(result, attempt)
    log(:warn,
        "retrying after #{sleep_for}s (attempt #{attempt}/#{@config.max_retries}): #{result.message}")
    sleep(sleep_for) if sleep_for.positive?
  end
end