Class: Raif::Utils::TransientRetry
- Inherits:
-
Object
- Object
- Raif::Utils::TransientRetry
- Defined in:
- lib/raif/utils/transient_retry.rb
Overview
Retries a block on transient errors using exponential backoff.
Single source of truth for "retry the HTTP call on a network blip" across Raif's synchronous (Raif::Llm#perform_model_completion!) and batch (Raif::Concerns::Llms::*::BatchInference) paths.
Defaults to Raif.config.llm_request_max_retries and Raif.config.llm_request_retriable_exceptions so retry behavior moves together when hosts tune those.
Constant Summary collapse
- DEFAULT_BASE_DELAY =
3- DEFAULT_MAX_DELAY =
30- DEFAULT_JITTER =
Fraction of each delay that is randomized away. Without it, N requests rate limited at the same moment retry at the same moment, and keep colliding for as many rounds as they have.
0.25- MAX_RETRY_AFTER_DELAY =
Ceiling on a provider-supplied Retry-After. That header is honored past max_delay, which bounds Raif's guess rather than the provider's own instruction - but a provider asking for an hour should not hang a run for one.
300
Class Method Summary collapse
-
.call(label:, max_retries: nil, retriable_exceptions: nil, base_delay: DEFAULT_BASE_DELAY, max_delay: DEFAULT_MAX_DELAY, jitter: DEFAULT_JITTER, on_retry: nil) { ... } ⇒ Object
Whatever the block returns on its successful attempt.
Class Method Details
.call(label:, max_retries: nil, retriable_exceptions: nil, base_delay: DEFAULT_BASE_DELAY, max_delay: DEFAULT_MAX_DELAY, jitter: DEFAULT_JITTER, on_retry: nil) { ... } ⇒ Object
Returns whatever the block returns on its successful attempt.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/raif/utils/transient_retry.rb', line 45 def self.call(label:, max_retries: nil, retriable_exceptions: nil, base_delay: DEFAULT_BASE_DELAY, max_delay: DEFAULT_MAX_DELAY, jitter: DEFAULT_JITTER, on_retry: nil) max_retries ||= Raif.config.llm_request_max_retries retriable_exceptions ||= Raif.config.llm_request_retriable_exceptions retriable_exceptions = Array(retriable_exceptions) attempt = 0 begin yield rescue *retriable_exceptions => e attempt += 1 if attempt <= max_retries delay = delay_for(e, attempt: attempt, base_delay: base_delay, max_delay: max_delay, jitter: jitter) on_retry&.call(e, attempt, max_retries, delay) Raif.logger.warn( "Raif::Utils::TransientRetry[#{label}]: retry #{attempt}/#{max_retries} " \ "after #{e.class}: #{e.}. Sleeping #{delay}s." ) sleep_for(delay) retry end Raif.logger.error( "Raif::Utils::TransientRetry[#{label}]: exhausted #{max_retries} retries. " \ "Last error: #{e.class}: #{e.}" ) raise end end |