Skip to content

Commit 04c5f0d

Browse files
FullyTypedAstraea Quinn S
authored andcommitted
parity: default retry presets
1 parent 20ad89e commit 04c5f0d

2 files changed

Lines changed: 433 additions & 16 deletions

File tree

src/aws_durable_execution_sdk_python/retries.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,48 @@
22

33
from __future__ import annotations
44

5-
from enum import StrEnum
5+
import math
66
import random
77
import re
8-
import sys
98
from dataclasses import dataclass, field
9+
from enum import StrEnum
1010
from typing import TYPE_CHECKING
1111

1212
if TYPE_CHECKING:
1313
from collections.abc import Callable
14-
from aws_durable_execution_sdk_python.types import JitterStrategy
1514

1615
Numeric = int | float
1716

1817
# region Jitter
1918

19+
2020
class JitterStrategy(StrEnum):
2121
"""
2222
Jitter strategies are used to introduce noise when attempting to retry
2323
an invoke. We introduce noise to prevent a thundering-herd effect where
2424
a group of accesses (e.g. invokes) happen at once.
2525
26-
Jitter is meant to be used to spread operations across time.
26+
Jitter is meant to be used to spread operations across time.
2727
2828
members:
2929
:NONE: No jitter; use the exact calculated delay
3030
:FULL: Full jitter; random delay between 0 and calculated delay
3131
:HALF: Half jitter; random delay between 0.5x and 1.0x of the calculated delay
3232
"""
33+
3334
NONE = "NONE"
3435
FULL = "FULL"
3536
HALF = "HALF"
3637

37-
def compute_jitter(self, delay) -> int:
38+
def compute_jitter(self, delay) -> float:
3839
match self:
3940
case JitterStrategy.NONE:
4041
return 0
41-
case JitterStrategy.FULL:
42-
return random.random() * delay # noqa: S311
4342
case JitterStrategy.HALF:
44-
return (random.random() * 0.5 + 0.5) # noqa: S311
43+
return random.random() * 0.5 + 0.5 # noqa: S311
44+
case _: # default is FULL
45+
return random.random() * delay # noqa: S311
46+
4547

4648
# endregion Jitter
4749

@@ -66,7 +68,7 @@ def no_retry(cls) -> RetryDecision:
6668

6769
@dataclass
6870
class RetryStrategyConfig:
69-
max_attempts: int = sys.maxsize # "infinite", practically
71+
max_attempts: int = 3 # "infinite", practically
7072
initial_delay_seconds: int = 5
7173
max_delay_seconds: int = 300 # 5 minutes
7274
backoff_rate: Numeric = 2.0
@@ -109,8 +111,9 @@ def retry_strategy(error: Exception, attempts_made: int) -> RetryDecision:
109111
config.initial_delay_seconds * (config.backoff_rate ** (attempts_made - 1)),
110112
config.max_delay_seconds,
111113
)
112-
jitter = config.jitter_strategy.compute_jitter(delay)
113-
final_delay = max(1, delay + jitter)
114+
delay_with_jitter = delay + config.jitter_strategy.compute_jitter(delay)
115+
delay_with_jitter = math.ceil(delay_with_jitter)
116+
final_delay = max(1, delay_with_jitter)
114117

115118
return RetryDecision.retry(round(final_delay))
116119

@@ -123,17 +126,18 @@ class RetryPresets:
123126
@classmethod
124127
def none(cls) -> Callable[[Exception, int], RetryDecision]:
125128
"""No retries."""
126-
return create_retry_strategy(RetryStrategyConfig(max_attempts=0))
129+
return create_retry_strategy(RetryStrategyConfig(max_attempts=1))
127130

128131
@classmethod
129132
def default(cls) -> Callable[[Exception, int], RetryDecision]:
130133
"""Default retries, will be used automatically if retryConfig is missing"""
131134
return create_retry_strategy(
132135
RetryStrategyConfig(
133-
max_attempts=sys.maxsize,
136+
max_attempts=6,
134137
initial_delay_seconds=5,
135138
max_delay_seconds=60,
136139
backoff_rate=2,
140+
jitter_strategy=JitterStrategy.FULL,
137141
)
138142
)
139143

@@ -142,9 +146,7 @@ def transient(cls) -> Callable[[Exception, int], RetryDecision]:
142146
"""Quick retries for transient errors"""
143147
return create_retry_strategy(
144148
RetryStrategyConfig(
145-
max_attempts=3,
146-
backoff_rate=2,
147-
jitter_seconds=0.5,
149+
max_attempts=3, backoff_rate=2, jitter_strategy=JitterStrategy.HALF
148150
)
149151
)
150152

@@ -169,5 +171,6 @@ def critical(cls) -> Callable[[Exception, int], RetryDecision]:
169171
initial_delay_seconds=1,
170172
max_delay_seconds=60,
171173
backoff_rate=1.5,
174+
jitter_strategy=JitterStrategy.NONE,
172175
)
173176
)

0 commit comments

Comments
 (0)