Module: Smith::PersistenceAdapters::Retry
- Defined in:
- lib/smith/persistence_adapters/retry.rb
Overview
Generic retry-with-exponential-backoff wrapper used by adapter store/fetch/delete/store_versioned operations to survive transient I/O errors. After attempts exhausted, raises Smith::PersistenceIOError wrapping the underlying cause.
Adapter-agnostic: each adapter passes its own ‘transient:` error class list because Redis transient errors differ from AR transient errors differ from cache-backend transient errors. The Memory adapter passes an empty list (it never raises transient errors).
Class Method Summary collapse
Class Method Details
.with_retries(operation:, transient:, policy: Smith.config.persistence_retry_policy, logger: Smith.config.logger) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/smith/persistence_adapters/retry.rb', line 17 def with_retries(operation:, transient:, policy: Smith.config.persistence_retry_policy, logger: Smith.config.logger) attempts = policy.fetch(:attempts, 3) base = policy.fetch(:base_delay, 0.1) max_delay = policy.fetch(:max_delay, 1.0) last_error = nil attempts.times do |i| return yield rescue *transient => e last_error = e break if i == attempts - 1 delay = [base * (2**i), max_delay].min logger&.warn( "Smith::PersistenceAdapters::Retry #{operation} attempt #{i + 1}/#{attempts} failed: " \ "#{e.class}: #{e.}; sleeping #{delay}s" ) sleep(delay) end raise Smith::PersistenceIOError.new(operation: operation, cause: last_error) end |