|
1 | 1 | """ |
2 | 2 | Lowest level connection |
3 | 3 | """ |
| 4 | +import sys |
4 | 5 | import logging |
5 | 6 | import uuid |
6 | 7 | from threading import local |
7 | | -from typing import Any, Dict, List, Mapping, Optional, Sequence, cast |
| 8 | +from typing import Any, Dict, List, Mapping, Optional, Sequence, Union, cast |
| 9 | +if sys.version_info >= (3, 8): |
| 10 | + from typing import Literal |
| 11 | +else: |
| 12 | + from typing_extensions import Literal |
8 | 13 |
|
9 | 14 | import botocore.client |
10 | 15 | import botocore.exceptions |
@@ -247,6 +252,7 @@ def __init__(self, |
247 | 252 | read_timeout_seconds: Optional[float] = None, |
248 | 253 | connect_timeout_seconds: Optional[float] = None, |
249 | 254 | max_retry_attempts: Optional[int] = None, |
| 255 | + retry_configuration: Optional[Union[Literal["LEGACY"], dict]] = None, |
250 | 256 | max_pool_connections: Optional[int] = None, |
251 | 257 | extra_headers: Optional[Mapping[str, str]] = None, |
252 | 258 | aws_access_key_id: Optional[str] = None, |
@@ -277,6 +283,11 @@ def __init__(self, |
277 | 283 | else: |
278 | 284 | self._max_retry_attempts_exception = get_settings_value('max_retry_attempts') |
279 | 285 |
|
| 286 | + if retry_configuration is not None: |
| 287 | + self._retry_configuration = retry_configuration |
| 288 | + else: |
| 289 | + self._retry_configuration = get_settings_value('retry_configuration') |
| 290 | + |
280 | 291 | if max_pool_connections is not None: |
281 | 292 | self._max_pool_connections = max_pool_connections |
282 | 293 | else: |
@@ -399,15 +410,22 @@ def client(self) -> BotocoreBaseClientPrivate: |
399 | 410 | # if the client does not have credentials, we create a new client |
400 | 411 | # otherwise the client is permanently poisoned in the case of metadata service flakiness when using IAM roles |
401 | 412 | if not self._client or (self._client._request_signer and not self._client._request_signer._credentials): |
| 413 | + # Check if we are using the "LEGACY" retry mode to keep previous PynamoDB |
| 414 | + # retry behavior, or if we are using the new retry configuration settings. |
| 415 | + if self._retry_configuration != "LEGACY": |
| 416 | + retries = self._retry_configuration |
| 417 | + else: |
| 418 | + retries = { |
| 419 | + 'total_max_attempts': 1 + self._max_retry_attempts_exception, |
| 420 | + 'mode': 'standard', |
| 421 | + } |
| 422 | + |
402 | 423 | config = botocore.client.Config( |
403 | 424 | parameter_validation=False, # Disable unnecessary validation for performance |
404 | 425 | connect_timeout=self._connect_timeout_seconds, |
405 | 426 | read_timeout=self._read_timeout_seconds, |
406 | 427 | max_pool_connections=self._max_pool_connections, |
407 | | - retries={ |
408 | | - 'total_max_attempts': 1 + self._max_retry_attempts_exception, |
409 | | - 'mode': 'standard', |
410 | | - } |
| 428 | + retries=retries |
411 | 429 | ) |
412 | 430 | self._client = cast(BotocoreBaseClientPrivate, self.session.create_client(SERVICE_NAME, self.region, endpoint_url=self.host, config=config)) |
413 | 431 |
|
|
0 commit comments