Module: ActiveJob::Temporal::RetryMapper
- Defined in:
- lib/activejob/temporal/retry_mapper.rb
Overview
Algorithmic Wait Values If ‘retry_on` uses a Proc or Symbol for `:wait` (e.g., `:exponentially_longer`), it falls back to the configured `default_retry_initial_interval` because Temporal only accepts static numeric intervals. Temporal’s built-in exponential backoff (via ‘backoff_coefficient`) is used instead.
Multiple retry_on Declarations If a job class has multiple ‘retry_on` declarations, the first matching handler (based on exception type) is used. Handlers are evaluated in reverse order of declaration (last declared = first matched).
Exponential Backoff Temporal automatically applies exponential backoff using backoff_coefficient. For example, with initial_interval=30s and backoff_coefficient=2.0, retries occur at 30s, 60s, 120s, 240s intervals (exponentially increasing).
Unlimited Retries Setting attempts: :unlimited translates to maximum_attempts: 0 in Temporal, which means the activity will retry indefinitely until it succeeds or is cancelled. Use this carefully to avoid infinite retry loops.
Exception Inheritance Exception matching respects inheritance. A retry_on StandardError declaration will match all StandardError subclasses (RuntimeError, ArgumentError, etc.). More specific exceptions should be declared last to take precedence.
Translates ActiveJob retry DSL to Temporal RetryPolicy.
This module introspects a job class’s ‘retry_on` and `discard_on` declarations and converts them into a Temporal-compatible retry policy hash. It handles:
-
Retry intervals (wait durations)
-
Retry attempt limits
-
Non-retryable error types (from discard_on)
The mapper uses Ruby’s internal ‘rescue_handlers` mechanism to extract retry configuration at runtime, ensuring compatibility with ActiveJob’s DSL.
Class Method Summary collapse
-
.discard_exception?(job_class, exception) ⇒ Boolean
Checks if an exception should be discarded (not retried).
- .exception_execution_keys(job_class) ⇒ Object
-
.for(job_class, exception = nil) ⇒ Hash
Builds a Temporal retry policy hash from a job class’s retry configuration.
- .retry_handler(job_class, exception) ⇒ Object
Class Method Details
.discard_exception?(job_class, exception) ⇒ Boolean
Checks if an exception should be discarded (not retried).
Inspects the job class’s ‘discard_on` declarations to determine if the given exception matches any discard handler. If true, the activity should raise a non-retryable error to stop Temporal from retrying.
157 158 159 |
# File 'lib/activejob/temporal/retry_mapper.rb', line 157 def discard_exception?(job_class, exception) extractor.discard_exception?(job_class, exception) end |
.exception_execution_keys(job_class) ⇒ Object
136 137 138 |
# File 'lib/activejob/temporal/retry_mapper.rb', line 136 def exception_execution_keys(job_class) extractor.retry_handlers(job_class).filter_map { |handler| handler[:exception_execution_key] }.uniq end |
.for(job_class, exception = nil) ⇒ Hash
Precedence of Multiple retry_on Declarations When a job class has multiple retry_on declarations, ActiveJob’s rescue_handlers are evaluated in reverse order (last declared = first matched). If you provide an exception argument, the first matching handler is used. Without an exception, the first handler in the list is used.
Builds a Temporal retry policy hash from a job class’s retry configuration.
Inspects the job class’s ‘retry_on` declarations and constructs a retry policy. If an exception is provided, selects the matching retry handler; otherwise uses the first retry handler found.
119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/activejob/temporal/retry_mapper.rb', line 119 def for(job_class, exception = nil) config = ActiveJob::Temporal.config retry_entries = extractor.retry_handlers(job_class) retry_entry = select_retry_entry(job_class, exception, retry_entries) { initial_interval: interval_from(retry_entry&.fetch(:wait, nil), config), backoff_coefficient: config.default_retry_backoff, maximum_attempts: maximum_attempts_from(retry_entries, retry_entry, exception, config, job_class), non_retryable_error_types: discard_exception_names(job_class) } end |
.retry_handler(job_class, exception) ⇒ Object
132 133 134 |
# File 'lib/activejob/temporal/retry_mapper.rb', line 132 def retry_handler(job_class, exception) select_retry_entry(job_class, exception) end |