Module: Heatwave::FaradayRetry
- Defined in:
- app/lib/heatwave/faraday_retry.rb
Overview
Project conventions for Faraday's +:retry+ middleware, replacing the
hand-rolled +Retryable.retryable(on: Retryable::TIMEOUT_CLASSES)+ wrappers
that used to guard outbound HTTP calls one call site at a time.
Apply it when building a Faraday connection:
Faraday.new(url: base) do |f|
f.request :retry, **Heatwave::FaradayRetry.options(tries: 3, base: 4)
f.request :json
f.adapter Faraday.default_adapter
end
The +:retry+ middleware backs off and retries the request inside the
connection, so callers no longer wrap each call in a block. It retries on
the transient transport failures in EXCEPTIONS and, optionally, on a set
of HTTP +retry_statuses+.
== Mapping Retryable semantics onto faraday-retry
The two libraries count and space attempts differently; FaradayRetry.options does the
translation so call sites read the same as the wrappers they replace:
Retryable faraday-retry (this helper)
tries: 3 (3 attempts total) max: 2 (2 retries)
sleep: ->(n){ 4**n } (1s, 4s, 16s, ...) interval: 1, backoff_factor: 4
sleep: 2 (constant 2s) interval: 2, backoff_factor: 1
on: TIMEOUT_CLASSES exceptions: EXCEPTIONS
Constant Summary collapse
- EXCEPTIONS =
Transient transport failures worth retrying. Mirrors the HTTP-relevant
subset of +Retryable::TIMEOUT_CLASSES+: once the http.rb adapter
(+Faraday.default_adapter == :http+) wraps a request, its own +HTTP::*+
timeout/connection errors surface as Faraday::TimeoutError /
Faraday::ConnectionFailed, so we retry the Faraday-flavored classes
plus the lower-level SSL/socket/DNS errors that can escape the adapter.Faraday::RetriableResponse is included so the +retry_statuses+ option
(when a call site opts into status-based retries) takes effect. [ Faraday::TimeoutError, Faraday::ConnectionFailed, Faraday::SSLError, Faraday::RetriableResponse, Timeout::Error, Net::ReadTimeout, Net::OpenTimeout, OpenSSL::SSL::SSLError, OpenSSL::SSL::SSLErrorWaitReadable, SocketError, # DNS resolution failures (getaddrinfo) Errno::ECONNREFUSED, # connection refused Errno::ECONNRESET, # peer reset mid-stream Errno::EHOSTUNREACH, # host unreachable Errno::ETIMEDOUT # kernel-level connect timeout ].freeze
- ALL_METHODS =
Every HTTP verb the legacy wrappers retried. The +Retryable+ blocks wrapped
the call regardless of method — EDI feed submissions are POSTs and were
retried on timeout — so we opt every verb in rather than accept
faraday-retry's idempotent-only default (IDEMPOTENT_METHODS). Call sites
that should only retry reads pass +methods: %i[get]+ explicitly. %i[delete get head options patch post put].freeze
- IDEMPOTENT_METHODS =
faraday-retry's safe default: the idempotent verbs only. Exposed so a
GET/PUT-only client can opt into the conservative set by name. %i[delete get head options put].freeze
Class Method Summary collapse
-
.options(tries: 3, base: 4, interval: 1, methods: ALL_METHODS, retry_statuses: [], exceptions: EXCEPTIONS) ⇒ Hash
Build the keyword options to splat into +f.request :retry+, translating the +Retryable+ +tries+/+sleep+ vocabulary into faraday-retry's +max+/+interval+/+backoff_factor+.
Class Method Details
.options(tries: 3, base: 4, interval: 1, methods: ALL_METHODS, retry_statuses: [], exceptions: EXCEPTIONS) ⇒ Hash
Build the keyword options to splat into +f.request :retry+, translating
the +Retryable+ +tries+/+sleep+ vocabulary into faraday-retry's
+max+/+interval+/+backoff_factor+.
102 103 104 105 106 107 108 109 110 111 |
# File 'app/lib/heatwave/faraday_retry.rb', line 102 def (tries: 3, base: 4, interval: 1, methods: ALL_METHODS, retry_statuses: [], exceptions: EXCEPTIONS) { max: [tries - 1, 0].max, interval: interval, backoff_factor: base, exceptions: exceptions, methods: methods, retry_statuses: retry_statuses } end |