Summary
Bring create_linear_retry_strategy to parity with create_retry_strategy (and with the JS SDK), by switching it to a config-object API and adding the capabilities it is currently missing: max_delay capping, jitter, and retryable_errors / retryable_error_types filtering. Share the common jitter / error-matching / delay-finalization logic between the two helpers so their behavior cannot drift.
This mirrors the JS change in aws/aws-durable-execution-sdk-js#652.
Current state (Python)
create_retry_strategy already uses a config dataclass with max_delay, jitter_strategy (default FULL), retryable_errors, and retryable_error_types.
create_linear_retry_strategy lags — it is still positional with none of those capabilities:
def create_linear_retry_strategy(
max_attempts: int = 6,
initial_delay: Duration | None = None,
increment: Duration | None = None,
) -> Callable[[Exception, int], RetryDecision]:
# "No jitter is applied and there is no upper cap on the delay"
So today the only way to get jitter, a max-delay cap, or error filtering with linear backoff is to hand-roll a strategy.
Proposed changes (mirroring JS #652)
- Introduce a
LinearRetryStrategyConfig (Duration-based) with: max_attempts, initial_delay, increment, max_delay, jitter_strategy, retryable_errors, retryable_error_types.
- Defaults aligned with
create_retry_strategy: jitter_strategy=FULL, max_delay=5 min, retry-all when neither error filter is set.
- Extract the shared logic used by both helpers (jitter application, retryable-error resolution + matching, and final delay clamp to an integer >= 1 second) into a common module, so the linear and exponential strategies share one implementation.
- Delay calculation:
base = min(initial_delay + increment * (attempts_made - 1), max_delay), then apply jitter, then clamp.
- Pin
RetryPresets.linear() to jitter=NONE so its documented deterministic 1s, 2s, 3s, 4s, 5s delays are preserved.
Breaking change
Same shape as JS #652:
- Signature changes from positional
(max_attempts, initial_delay, increment) to a config object.
- Default jitter changes from none to
FULL, so a bare create_linear_retry_strategy() now yields jittered delays rather than the deterministic 1s-5s. (RetryPresets.linear() stays deterministic via jitter=NONE.)
Reference
Summary
Bring
create_linear_retry_strategyto parity withcreate_retry_strategy(and with the JS SDK), by switching it to a config-object API and adding the capabilities it is currently missing:max_delaycapping, jitter, andretryable_errors/retryable_error_typesfiltering. Share the common jitter / error-matching / delay-finalization logic between the two helpers so their behavior cannot drift.This mirrors the JS change in aws/aws-durable-execution-sdk-js#652.
Current state (Python)
create_retry_strategyalready uses a config dataclass withmax_delay,jitter_strategy(defaultFULL),retryable_errors, andretryable_error_types.create_linear_retry_strategylags — it is still positional with none of those capabilities:So today the only way to get jitter, a max-delay cap, or error filtering with linear backoff is to hand-roll a strategy.
Proposed changes (mirroring JS #652)
LinearRetryStrategyConfig(Duration-based) with:max_attempts,initial_delay,increment,max_delay,jitter_strategy,retryable_errors,retryable_error_types.create_retry_strategy:jitter_strategy=FULL,max_delay=5 min, retry-all when neither error filter is set.base = min(initial_delay + increment * (attempts_made - 1), max_delay), then apply jitter, then clamp.RetryPresets.linear()tojitter=NONEso its documented deterministic 1s, 2s, 3s, 4s, 5s delays are preserved.Breaking change
Same shape as JS #652:
(max_attempts, initial_delay, increment)to a config object.FULL, so a barecreate_linear_retry_strategy()now yields jittered delays rather than the deterministic 1s-5s. (RetryPresets.linear()stays deterministic viajitter=NONE.)Reference
create_retry_strategyis already config-shaped and is the model to follow for the linear helper.