Class: Quonfig::HttpConnection

Inherits:
Object
  • Object
show all
Defined in:
lib/quonfig/http_connection.rb

Constant Summary collapse

SDK_VERSION =
"ruby-#{Quonfig::VERSION}".freeze
JSON_HEADERS =
{
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'X-Quonfig-SDK-Version' => SDK_VERSION
}.freeze
WALL_CLOCK_HEADROOM_S =

qfg-41nh.6 (WS2.4): headroom added to timeout_ms to form the WALL-CLOCK ceiling for the whole request. Faraday's open/read timeouts are per-phase and — on the Net::HTTP adapter — per-READ: every byte that arrives resets the read deadline, so a slow-drip upstream (one byte per interval) holds a "bounded" request open indefinitely and wedges the caller (init fetch, fallback poll tick, hedge drain). The wall clock is the true per-leg abort (sdk-go's per-leg context deadline is wall-clock). The headroom keeps Faraday's own, more specific phase timeouts winning the simple-stall race; the wall clock only fires on drip-feed pathologies that per-read deadlines structurally cannot catch.

0.25

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(uri, sdk_key, timeout_ms: nil) ⇒ HttpConnection

timeout_ms (qfg-7h5d.1.9): per-request bound applied to BOTH the connect (open) and read phases of every request made through this connection, AND (qfg-41nh.6) enforced as a wall-clock ceiling over the whole request. nil leaves Faraday's defaults (no timeout) in place — preserving the prior behavior for callers that don't pass one. The config-fetch path passes Options#config_fetch_timeout_ms (sequential) or the hedge abort (hedged legs) so a hung OR drip-feeding upstream aborts fast instead of blocking the caller's whole init budget.



37
38
39
40
41
# File 'lib/quonfig/http_connection.rb', line 37

def initialize(uri, sdk_key, timeout_ms: nil)
  @uri = uri
  @sdk_key = sdk_key
  @timeout_ms = timeout_ms
end

Instance Attribute Details

#uriObject (readonly)

Returns the value of attribute uri.



43
44
45
# File 'lib/quonfig/http_connection.rb', line 43

def uri
  @uri
end

Instance Method Details

#connection(headers = {}) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/quonfig/http_connection.rb', line 53

def connection(headers = {})
  merged = JSON_HEADERS.merge('Authorization' => auth_header).merge(headers)
  Faraday.new(@uri) do |conn|
    conn.headers.merge!(merged)
    if @timeout_ms
      seconds = @timeout_ms / 1000.0
      # open_timeout bounds the TCP connect; timeout bounds the read. A
      # 'timeout' toxic accepts the connection but never sends bytes, so the
      # read deadline is the one that fires — set both so a refused/slow
      # connect is bounded too.
      conn.options.open_timeout = seconds
      conn.options.timeout = seconds
    end
  end
end

#get(path, headers = {}) ⇒ Object



45
46
47
# File 'lib/quonfig/http_connection.rb', line 45

def get(path, headers = {})
  with_wall_clock_deadline { connection(headers).get(path) }
end

#post(path, body) ⇒ Object



49
50
51
# File 'lib/quonfig/http_connection.rb', line 49

def post(path, body)
  with_wall_clock_deadline { connection.post(path, body.to_json) }
end