Skip to content

Commit 0be8d52

Browse files
committed
Make retries config consistent in sync and async
1 parent f4a0be3 commit 0be8d52

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

redis/asyncio/client.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ def __init__(
158158
encoding_errors: str = "strict",
159159
decode_responses: bool = False,
160160
retry_on_timeout: bool = False,
161+
retry_on_error: Optional[list] = None,
161162
ssl: bool = False,
162163
ssl_keyfile: Optional[str] = None,
163164
ssl_certfile: Optional[str] = None,
@@ -176,8 +177,10 @@ def __init__(
176177
):
177178
"""
178179
Initialize a new Redis client.
179-
To specify a retry policy, first set `retry_on_timeout` to `True`
180-
then set `retry` to a valid `Retry` object
180+
To specify a retry policy for specific errors, first set
181+
`retry_on_error` to a list of the error/s to retry on, then set
182+
`retry` to a valid `Retry` object.
183+
To retry on TimeoutError, `retry_on_timeout` can also be set to `True`.
181184
"""
182185
kwargs: Dict[str, Any]
183186
# auto_close_connection_pool only has an effect if connection_pool is
@@ -188,6 +191,10 @@ def __init__(
188191
auto_close_connection_pool if connection_pool is None else False
189192
)
190193
if not connection_pool:
194+
if not retry_on_error:
195+
retry_on_error = []
196+
if retry_on_timeout is True:
197+
retry_on_error.append(TimeoutError)
191198
kwargs = {
192199
"db": db,
193200
"username": username,
@@ -197,6 +204,7 @@ def __init__(
197204
"encoding_errors": encoding_errors,
198205
"decode_responses": decode_responses,
199206
"retry_on_timeout": retry_on_timeout,
207+
"retry_on_error": retry_on_error,
200208
"retry": copy.deepcopy(retry),
201209
"max_connections": max_connections,
202210
"health_check_interval": health_check_interval,

redis/asyncio/connection.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ class Connection:
578578
"socket_type",
579579
"redis_connect_func",
580580
"retry_on_timeout",
581+
"retry_on_error",
581582
"health_check_interval",
582583
"next_health_check",
583584
"last_active_at",
@@ -606,6 +607,7 @@ def __init__(
606607
socket_keepalive_options: Optional[Mapping[int, Union[int, bytes]]] = None,
607608
socket_type: int = 0,
608609
retry_on_timeout: bool = False,
610+
retry_on_error: Union[list, _Sentinel] = SENTINEL,
609611
encoding: str = "utf-8",
610612
encoding_errors: str = "strict",
611613
decode_responses: bool = False,
@@ -631,12 +633,19 @@ def __init__(
631633
self.socket_keepalive_options = socket_keepalive_options or {}
632634
self.socket_type = socket_type
633635
self.retry_on_timeout = retry_on_timeout
636+
if retry_on_error is SENTINEL:
637+
retry_on_error = []
634638
if retry_on_timeout:
639+
retry_on_error.append(TimeoutError)
640+
self.retry_on_error = retry_on_error
641+
if retry_on_error:
635642
if not retry:
636643
self.retry = Retry(NoBackoff(), 1)
637644
else:
638645
# deep-copy the Retry object as it is mutable
639646
self.retry = copy.deepcopy(retry)
647+
# Update the retry's supported errors with the specified errors
648+
self.retry.update_supported_errors(retry_on_error)
640649
else:
641650
self.retry = Retry(NoBackoff(), 0)
642651
self.health_check_interval = health_check_interval
@@ -1169,6 +1178,7 @@ def __init__(
11691178
encoding_errors: str = "strict",
11701179
decode_responses: bool = False,
11711180
retry_on_timeout: bool = False,
1181+
retry_on_error: Union[list, _Sentinel] = SENTINEL,
11721182
parser_class: Type[BaseParser] = DefaultParser,
11731183
socket_read_size: int = 65536,
11741184
health_check_interval: float = 0.0,
@@ -1190,12 +1200,18 @@ def __init__(
11901200
self.socket_timeout = socket_timeout
11911201
self.socket_connect_timeout = socket_connect_timeout or socket_timeout or None
11921202
self.retry_on_timeout = retry_on_timeout
1203+
if retry_on_error is SENTINEL:
1204+
retry_on_error = []
11931205
if retry_on_timeout:
1206+
retry_on_error.append(TimeoutError)
1207+
if retry_on_error:
11941208
if retry is None:
11951209
self.retry = Retry(NoBackoff(), 1)
11961210
else:
11971211
# deep-copy the Retry object as it is mutable
11981212
self.retry = copy.deepcopy(retry)
1213+
# Update the retry's supported errors with the specified errors
1214+
self.retry.update_supported_errors(retry_on_error)
11991215
else:
12001216
self.retry = Retry(NoBackoff(), 0)
12011217
self.health_check_interval = health_check_interval

redis/asyncio/retry.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ def __init__(
3535
self._retries = retries
3636
self._supported_errors = supported_errors
3737

38+
def update_supported_errors(self, specified_errors: list):
39+
"""
40+
Updates the supported errors with the specified error types
41+
"""
42+
self._supported_errors = tuple(
43+
set(self._supported_errors + tuple(specified_errors))
44+
)
45+
3846
async def call_with_retry(
3947
self, do: Callable[[], Awaitable[T]], fail: Callable[[RedisError], Any]
4048
) -> T:

0 commit comments

Comments
 (0)