Module: LanguageOperator::Retry
- Defined in:
- lib/language_operator/retry.rb
Overview
Retry utilities with exponential backoff for handling transient failures
Constant Summary collapse
- DEFAULT_MAX_RETRIES =
Default retry configuration
3- DEFAULT_BASE_DELAY =
1.0- DEFAULT_MAX_DELAY =
10.0- DEFAULT_JITTER_FACTOR =
0.1- RETRYABLE_HTTP_CODES =
Common retryable HTTP status codes (transient errors)
[429, 500, 502, 503, 504].freeze
Class Method Summary collapse
-
.calculate_backoff(attempt, base_delay = DEFAULT_BASE_DELAY, max_delay = DEFAULT_MAX_DELAY, jitter_factor = DEFAULT_JITTER_FACTOR) ⇒ Float
Calculate exponential backoff delay with jitter.
-
.on_exceptions(exception_types, max_retries: DEFAULT_MAX_RETRIES, base_delay: DEFAULT_BASE_DELAY, max_delay: DEFAULT_MAX_DELAY, jitter_factor: DEFAULT_JITTER_FACTOR) { ... } ⇒ Object
Execute a block with retry for specific exception types.
-
.retryable_http_code?(status) ⇒ Boolean
Check if an HTTP status code is retryable (transient error).
-
.with_backoff(max_retries: DEFAULT_MAX_RETRIES, base_delay: DEFAULT_BASE_DELAY, max_delay: DEFAULT_MAX_DELAY, jitter_factor: DEFAULT_JITTER_FACTOR, on_retry: nil) { ... } ⇒ Object
Execute a block with exponential backoff retry logic.
Class Method Details
.calculate_backoff(attempt, base_delay = DEFAULT_BASE_DELAY, max_delay = DEFAULT_MAX_DELAY, jitter_factor = DEFAULT_JITTER_FACTOR) ⇒ Float
Calculate exponential backoff delay with jitter
110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/language_operator/retry.rb', line 110 def self.calculate_backoff(attempt, base_delay = DEFAULT_BASE_DELAY, max_delay = DEFAULT_MAX_DELAY, jitter_factor = DEFAULT_JITTER_FACTOR) # Exponential: base * 2^(attempt-1) exponential = base_delay * (2**(attempt - 1)) # Cap at max capped = [exponential, max_delay].min # Add jitter: ±(delay * jitter_factor * random) jitter = capped * jitter_factor * (rand - 0.5) * 2 capped + jitter end |
.on_exceptions(exception_types, max_retries: DEFAULT_MAX_RETRIES, base_delay: DEFAULT_BASE_DELAY, max_delay: DEFAULT_MAX_DELAY, jitter_factor: DEFAULT_JITTER_FACTOR) { ... } ⇒ Object
Execute a block with retry for specific exception types
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/language_operator/retry.rb', line 70 def self.on_exceptions(exception_types, max_retries: DEFAULT_MAX_RETRIES, base_delay: DEFAULT_BASE_DELAY, max_delay: DEFAULT_MAX_DELAY, jitter_factor: DEFAULT_JITTER_FACTOR) attempt = 0 begin yield rescue *exception_types => e if attempt < max_retries attempt += 1 delay = calculate_backoff(attempt, base_delay, max_delay, jitter_factor) sleep delay retry end raise e end end |
.retryable_http_code?(status) ⇒ Boolean
Check if an HTTP status code is retryable (transient error)
95 96 97 |
# File 'lib/language_operator/retry.rb', line 95 def self.retryable_http_code?(status) RETRYABLE_HTTP_CODES.include?(status) end |
.with_backoff(max_retries: DEFAULT_MAX_RETRIES, base_delay: DEFAULT_BASE_DELAY, max_delay: DEFAULT_MAX_DELAY, jitter_factor: DEFAULT_JITTER_FACTOR, on_retry: nil) { ... } ⇒ Object
Execute a block with exponential backoff retry logic
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/language_operator/retry.rb', line 36 def self.with_backoff(max_retries: DEFAULT_MAX_RETRIES, base_delay: DEFAULT_BASE_DELAY, max_delay: DEFAULT_MAX_DELAY, jitter_factor: DEFAULT_JITTER_FACTOR, on_retry: nil) attempt = 0 begin yield rescue StandardError => e if attempt < max_retries attempt += 1 delay = calculate_backoff(attempt, base_delay, max_delay, jitter_factor) on_retry&.call(attempt, e) sleep delay retry end raise e end end |