0
# Retry & Backoff
1
2
Flexible retry mechanisms with configurable retry conditions and backoff strategies for handling transient failures, rate limiting, and network issues. The SDK provides comprehensive retry policies to improve reliability and resilience.
3
4
## Capabilities
5
6
### Retry Policy
7
8
Main retry policy class that combines retry conditions and backoff strategies to define complete retry behavior.
9
10
```python { .api }
11
class RetryPolicy(RetryCondition, BackoffStrategy):
12
def __init__(self, retry_condition, backoff_strategy):
13
"""
14
Initialize retry policy with condition and backoff strategy.
15
16
Parameters:
17
- retry_condition (RetryCondition): Condition determining when to retry
18
- backoff_strategy (BackoffStrategy): Strategy for delay between retries
19
"""
20
21
def should_retry(self, retry_policy_context):
22
"""
23
Determine if request should be retried based on the condition.
24
25
Parameters:
26
- retry_policy_context (RetryPolicyContext): Context with attempt info
27
28
Returns:
29
bool: True if request should be retried
30
"""
31
32
def compute_delay_before_next_retry(self, retry_policy_context):
33
"""
34
Calculate delay before next retry attempt.
35
36
Parameters:
37
- retry_policy_context (RetryPolicyContext): Context with attempt info
38
39
Returns:
40
float: Delay in seconds before next retry
41
"""
42
```
43
44
### Retry Conditions
45
46
Base class and implementations for different retry conditions that determine when requests should be retried.
47
48
```python { .api }
49
class RetryCondition:
50
def should_retry(self, retry_policy_context):
51
"""
52
Abstract method to determine if retry should be attempted.
53
54
Parameters:
55
- retry_policy_context (RetryPolicyContext): Context with attempt info
56
57
Returns:
58
bool: True if retry should be attempted
59
"""
60
61
class NoRetryCondition(RetryCondition):
62
"""Condition that never retries."""
63
64
class MaxRetryTimesCondition(RetryCondition):
65
def __init__(self, max_retry_times):
66
"""
67
Retry condition based on maximum number of attempts.
68
69
Parameters:
70
- max_retry_times (int): Maximum number of retry attempts
71
"""
72
73
class RetryOnExceptionCondition(RetryCondition):
74
def __init__(self, retryable_exceptions):
75
"""
76
Retry condition based on specific exception types.
77
78
Parameters:
79
- retryable_exceptions (list): List of exception types that should trigger retry
80
"""
81
82
class RetryOnHttpStatusCondition(RetryCondition):
83
def __init__(self, retryable_status_codes):
84
"""
85
Retry condition based on HTTP status codes.
86
87
Parameters:
88
- retryable_status_codes (list): List of HTTP status codes that should trigger retry
89
"""
90
91
class RetryOnApiCondition(RetryCondition):
92
def __init__(self, retryable_error_codes):
93
"""
94
Retry condition based on API error codes.
95
96
Parameters:
97
- retryable_error_codes (list): List of API error codes that should trigger retry
98
"""
99
```
100
101
### Backoff Strategies
102
103
Different backoff strategies for controlling the delay between retry attempts.
104
105
```python { .api }
106
class BackoffStrategy:
107
def compute_delay_before_next_retry(self, retry_policy_context):
108
"""
109
Abstract method to compute delay before next retry.
110
111
Parameters:
112
- retry_policy_context (RetryPolicyContext): Context with attempt info
113
114
Returns:
115
float: Delay in seconds
116
"""
117
118
class FixedDelayStrategy(BackoffStrategy):
119
def __init__(self, fixed_delay):
120
"""
121
Fixed delay strategy with constant interval between retries.
122
123
Parameters:
124
- fixed_delay (float): Fixed delay in seconds between retries
125
"""
126
127
class NoDelayStrategy(FixedDelayStrategy):
128
"""No delay strategy for immediate retries."""
129
130
class ExponentialBackoffStrategy(BackoffStrategy):
131
def __init__(self, base_delay=1.0, max_delay=60.0, multiplier=2.0):
132
"""
133
Exponential backoff strategy with increasing delays.
134
135
Parameters:
136
- base_delay (float): Initial delay in seconds, defaults to 1.0
137
- max_delay (float): Maximum delay in seconds, defaults to 60.0
138
- multiplier (float): Multiplier for each retry, defaults to 2.0
139
"""
140
141
class JitteredExponentialBackoffStrategy(ExponentialBackoffStrategy):
142
def __init__(self, base_delay=1.0, max_delay=60.0, multiplier=2.0):
143
"""
144
Exponential backoff with random jitter to avoid thundering herd.
145
146
Parameters:
147
- base_delay (float): Initial delay in seconds
148
- max_delay (float): Maximum delay in seconds
149
- multiplier (float): Multiplier for each retry
150
"""
151
```
152
153
### Retry Policy Context
154
155
Context object that tracks retry attempt information and provides data to retry conditions and backoff strategies.
156
157
```python { .api }
158
class RetryPolicyContext:
159
def __init__(self):
160
"""Initialize retry policy context for tracking attempt information."""
161
162
def get_retrials_attempted(self):
163
"""
164
Get the number of retry attempts made so far.
165
166
Returns:
167
int: Number of retries attempted
168
"""
169
170
def get_exception(self):
171
"""
172
Get the exception that triggered the retry consideration.
173
174
Returns:
175
Exception: The exception from the failed attempt
176
"""
177
178
def get_original_request(self):
179
"""
180
Get the original request being retried.
181
182
Returns:
183
AcsRequest: The original request object
184
"""
185
```
186
187
### Composite Retry Conditions
188
189
Advanced retry conditions that combine multiple conditions with logical operators.
190
191
```python { .api }
192
class AndRetryCondition(RetryCondition):
193
def __init__(self, *conditions):
194
"""
195
Retry condition that requires ALL conditions to be true.
196
197
Parameters:
198
- conditions: Variable number of RetryCondition objects
199
"""
200
201
class OrRetryCondition(RetryCondition):
202
def __init__(self, *conditions):
203
"""
204
Retry condition that requires ANY condition to be true.
205
206
Parameters:
207
- conditions: Variable number of RetryCondition objects
208
"""
209
210
class MixedRetryCondition(RetryCondition):
211
"""Complex retry condition combining multiple criteria."""
212
213
class DefaultConfigRetryCondition(MixedRetryCondition):
214
"""Default retry condition with reasonable settings for most use cases."""
215
```
216
217
## Usage Examples
218
219
### Basic Retry Configuration
220
221
```python
222
from aliyunsdkcore.client import AcsClient
223
from aliyunsdkcore.retry.retry_policy import RetryPolicy
224
from aliyunsdkcore.retry.retry_condition import MaxRetryTimesCondition
225
from aliyunsdkcore.retry.backoff_strategy import FixedDelayStrategy
226
227
# Create retry policy with fixed delay
228
retry_condition = MaxRetryTimesCondition(max_retry_times=3)
229
backoff_strategy = FixedDelayStrategy(fixed_delay=2.0)
230
retry_policy = RetryPolicy(retry_condition, backoff_strategy)
231
232
# Configure client with retry policy
233
client = AcsClient(
234
ak="your-ak",
235
secret="your-secret",
236
region_id="cn-hangzhou",
237
auto_retry=True,
238
max_retry_time=3
239
)
240
```
241
242
### Exponential Backoff with Jitter
243
244
```python
245
from aliyunsdkcore.retry.backoff_strategy import JitteredExponentialBackoffStrategy
246
from aliyunsdkcore.retry.retry_condition import MaxRetryTimesCondition
247
248
# Create exponential backoff with jitter
249
retry_condition = MaxRetryTimesCondition(max_retry_times=5)
250
backoff_strategy = JitteredExponentialBackoffStrategy(
251
base_delay=1.0,
252
max_delay=30.0,
253
multiplier=2.0
254
)
255
retry_policy = RetryPolicy(retry_condition, backoff_strategy)
256
257
client = AcsClient(
258
ak="your-ak",
259
secret="your-secret",
260
region_id="cn-hangzhou",
261
retry_policy=retry_policy
262
)
263
```
264
265
### Exception-Based Retry
266
267
```python
268
from aliyunsdkcore.retry.retry_condition import RetryOnExceptionCondition
269
from aliyunsdkcore.acs_exception.exceptions import ClientException, ServerException
270
271
# Retry on specific exceptions
272
retryable_exceptions = [
273
ClientException, # Network or client errors
274
# Add other exception types as needed
275
]
276
277
retry_condition = RetryOnExceptionCondition(retryable_exceptions)
278
backoff_strategy = ExponentialBackoffStrategy(base_delay=2.0, max_delay=60.0)
279
retry_policy = RetryPolicy(retry_condition, backoff_strategy)
280
```
281
282
### HTTP Status Code Based Retry
283
284
```python
285
from aliyunsdkcore.retry.retry_condition import RetryOnHttpStatusCondition
286
287
# Retry on specific HTTP status codes
288
retryable_status_codes = [
289
429, # Too Many Requests
290
500, # Internal Server Error
291
502, # Bad Gateway
292
503, # Service Unavailable
293
504, # Gateway Timeout
294
]
295
296
retry_condition = RetryOnHttpStatusCondition(retryable_status_codes)
297
backoff_strategy = JitteredExponentialBackoffStrategy()
298
retry_policy = RetryPolicy(retry_condition, backoff_strategy)
299
```
300
301
### API Error Code Based Retry
302
303
```python
304
from aliyunsdkcore.retry.retry_condition import RetryOnApiCondition
305
306
# Retry on specific API error codes
307
retryable_error_codes = [
308
"Throttling",
309
"ServiceUnavailable",
310
"InternalError",
311
"RequestTimeout"
312
]
313
314
retry_condition = RetryOnApiCondition(retryable_error_codes)
315
backoff_strategy = ExponentialBackoffStrategy()
316
retry_policy = RetryPolicy(retry_condition, backoff_strategy)
317
```
318
319
### Complex Retry Conditions
320
321
```python
322
from aliyunsdkcore.retry.retry_condition import AndRetryCondition, OrRetryCondition
323
324
# Combine multiple conditions with AND logic
325
max_retries = MaxRetryTimesCondition(max_retry_times=3)
326
http_status = RetryOnHttpStatusCondition([500, 502, 503])
327
and_condition = AndRetryCondition(max_retries, http_status)
328
329
# Combine multiple conditions with OR logic
330
exception_condition = RetryOnExceptionCondition([ClientException])
331
api_condition = RetryOnApiCondition(["Throttling"])
332
or_condition = OrRetryCondition(exception_condition, api_condition)
333
334
# Use complex condition
335
retry_policy = RetryPolicy(or_condition, ExponentialBackoffStrategy())
336
```
337
338
### Custom Retry Implementation
339
340
```python
341
import time
342
import random
343
from aliyunsdkcore.acs_exception.exceptions import ClientException, ServerException
344
345
def custom_retry_request(client, request, max_retries=3):
346
"""
347
Custom retry implementation with exponential backoff and jitter.
348
"""
349
350
for attempt in range(max_retries + 1):
351
try:
352
response = client.do_action_with_exception(request)
353
return response.decode('utf-8')
354
355
except (ClientException, ServerException) as e:
356
if attempt == max_retries:
357
raise # Re-raise on final attempt
358
359
# Determine if we should retry
360
should_retry = False
361
362
if isinstance(e, ClientException):
363
# Retry on network/timeout errors
364
if e.get_error_code() in ["SDK.NetworkError", "SDK.TimeoutError"]:
365
should_retry = True
366
367
elif isinstance(e, ServerException):
368
# Retry on throttling and 5xx errors
369
if (e.get_error_code() == "Throttling" or
370
(e.get_http_status() and e.get_http_status() >= 500)):
371
should_retry = True
372
373
if should_retry:
374
# Exponential backoff with jitter
375
base_delay = 2.0
376
max_delay = 60.0
377
backoff = min(base_delay * (2 ** attempt), max_delay)
378
jitter = random.uniform(0, backoff * 0.1) # 10% jitter
379
delay = backoff + jitter
380
381
print(f"Retrying in {delay:.2f} seconds (attempt {attempt + 1})")
382
time.sleep(delay)
383
else:
384
raise # Don't retry non-retryable errors
385
386
# Usage
387
try:
388
result = custom_retry_request(client, request, max_retries=5)
389
print("Success:", result)
390
except Exception as e:
391
print(f"Failed after retries: {e}")
392
```
393
394
### Default Retry Configuration
395
396
```python
397
from aliyunsdkcore.retry.retry_condition import DefaultConfigRetryCondition
398
from aliyunsdkcore.retry.backoff_strategy import DefaultMixedBackoffStrategy
399
400
# Use default configurations for common scenarios
401
retry_condition = DefaultConfigRetryCondition()
402
backoff_strategy = DefaultMixedBackoffStrategy()
403
retry_policy = RetryPolicy(retry_condition, backoff_strategy)
404
405
# Apply to client
406
client = AcsClient(
407
ak="your-ak",
408
secret="your-secret",
409
region_id="cn-hangzhou",
410
auto_retry=True,
411
retry_policy=retry_policy
412
)
413
```
414
415
### Monitoring Retry Attempts
416
417
```python
418
import logging
419
from aliyunsdkcore.retry.retry_policy_context import RetryPolicyContext
420
421
logger = logging.getLogger(__name__)
422
423
class LoggingRetryPolicy(RetryPolicy):
424
"""Custom retry policy with logging."""
425
426
def should_retry(self, retry_policy_context):
427
should_retry = super().should_retry(retry_policy_context)
428
429
if should_retry:
430
attempt = retry_policy_context.get_retrials_attempted()
431
exception = retry_policy_context.get_exception()
432
logger.info(f"Retrying request (attempt {attempt + 1}): {exception}")
433
434
return should_retry
435
436
def compute_delay_before_next_retry(self, retry_policy_context):
437
delay = super().compute_delay_before_next_retry(retry_policy_context)
438
logger.info(f"Waiting {delay:.2f} seconds before retry")
439
return delay
440
441
# Use logging retry policy
442
retry_policy = LoggingRetryPolicy(
443
MaxRetryTimesCondition(3),
444
ExponentialBackoffStrategy()
445
)
446
```