Skip to content

Commit edd304a

Browse files
committed
Fix retry logic for pubsub and pipeline
Extend the fix from bea7299 to apply to pipeline and pubsub as well. Fixes redis#2973
1 parent 1a7d474 commit edd304a

File tree

2 files changed

+57
-29
lines changed

2 files changed

+57
-29
lines changed

redis/asyncio/client.py

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -924,11 +924,15 @@ async def connect(self):
924924
async def _disconnect_raise_connect(self, conn, error):
925925
"""
926926
Close the connection and raise an exception
927-
if retry_on_timeout is not set or the error
928-
is not a TimeoutError. Otherwise, try to reconnect
927+
if retry_on_error is not set or the error is not one
928+
of the specified error types. Otherwise, try to
929+
reconnect
929930
"""
930931
await conn.disconnect()
931-
if not (conn.retry_on_timeout and isinstance(error, TimeoutError)):
932+
if (
933+
conn.retry_on_error is None
934+
or isinstance(error, tuple(conn.retry_on_error)) is False
935+
):
932936
raise error
933937
await conn.connect()
934938

@@ -1341,8 +1345,8 @@ async def _disconnect_reset_raise(self, conn, error):
13411345
"""
13421346
Close the connection, reset watching state and
13431347
raise an exception if we were watching,
1344-
retry_on_timeout is not set,
1345-
or the error is not a TimeoutError
1348+
if retry_on_error is not set or the error is not one
1349+
of the specified error types.
13461350
"""
13471351
await conn.disconnect()
13481352
# if we were already watching a variable, the watch is no longer
@@ -1353,9 +1357,12 @@ async def _disconnect_reset_raise(self, conn, error):
13531357
raise WatchError(
13541358
"A ConnectionError occurred on while watching one or more keys"
13551359
)
1356-
# if retry_on_timeout is not set, or the error is not
1357-
# a TimeoutError, raise it
1358-
if not (conn.retry_on_timeout and isinstance(error, TimeoutError)):
1360+
# if retry_on_error is not set or the error is not one
1361+
# of the specified error types, raise it
1362+
if (
1363+
conn.retry_on_error is None
1364+
or isinstance(error, tuple(conn.retry_on_error)) is False
1365+
):
13591366
await self.aclose()
13601367
raise
13611368

@@ -1530,8 +1537,8 @@ async def load_scripts(self):
15301537
async def _disconnect_raise_reset(self, conn: Connection, error: Exception):
15311538
"""
15321539
Close the connection, raise an exception if we were watching,
1533-
and raise an exception if retry_on_timeout is not set,
1534-
or the error is not a TimeoutError
1540+
and raise an exception if retry_on_error is not set or the
1541+
error is not one of the specified error types.
15351542
"""
15361543
await conn.disconnect()
15371544
# if we were watching a variable, the watch is no longer valid
@@ -1541,9 +1548,12 @@ async def _disconnect_raise_reset(self, conn: Connection, error: Exception):
15411548
raise WatchError(
15421549
"A ConnectionError occurred on while watching one or more keys"
15431550
)
1544-
# if retry_on_timeout is not set, or the error is not
1545-
# a TimeoutError, raise it
1546-
if not (conn.retry_on_timeout and isinstance(error, TimeoutError)):
1551+
# if retry_on_error is not set or the error is not one
1552+
# of the specified error types, raise it
1553+
if (
1554+
conn.retry_on_error is None
1555+
or isinstance(error, tuple(conn.retry_on_error)) is False
1556+
):
15471557
await self.reset()
15481558
raise
15491559

redis/client.py

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@
2525
SentinelCommands,
2626
list_or_args,
2727
)
28-
from redis.connection import ConnectionPool, SSLConnection, UnixDomainSocketConnection
28+
from redis.connection import (
29+
ConnectionPool,
30+
SSLConnection,
31+
UnixDomainSocketConnection,
32+
AbstractConnection,
33+
)
2934
from redis.credentials import CredentialProvider
3035
from redis.exceptions import (
3136
ConnectionError,
@@ -837,11 +842,15 @@ def clean_health_check_responses(self) -> None:
837842
def _disconnect_raise_connect(self, conn, error) -> None:
838843
"""
839844
Close the connection and raise an exception
840-
if retry_on_timeout is not set or the error
841-
is not a TimeoutError. Otherwise, try to reconnect
845+
if retry_on_error is not set or the error is not one
846+
of the specified error types. Otherwise, try to
847+
reconnect
842848
"""
843849
conn.disconnect()
844-
if not (conn.retry_on_timeout and isinstance(error, TimeoutError)):
850+
if (
851+
conn.retry_on_error is None
852+
or isinstance(error, tuple(conn.retry_on_error)) is False
853+
):
845854
raise error
846855
conn.connect()
847856

@@ -1318,8 +1327,8 @@ def _disconnect_reset_raise(self, conn, error) -> None:
13181327
"""
13191328
Close the connection, reset watching state and
13201329
raise an exception if we were watching,
1321-
retry_on_timeout is not set,
1322-
or the error is not a TimeoutError
1330+
if retry_on_error is not set or the error is not one
1331+
of the specified error types.
13231332
"""
13241333
conn.disconnect()
13251334
# if we were already watching a variable, the watch is no longer
@@ -1330,9 +1339,12 @@ def _disconnect_reset_raise(self, conn, error) -> None:
13301339
raise WatchError(
13311340
"A ConnectionError occurred on while watching one or more keys"
13321341
)
1333-
# if retry_on_timeout is not set, or the error is not
1334-
# a TimeoutError, raise it
1335-
if not (conn.retry_on_timeout and isinstance(error, TimeoutError)):
1342+
# if retry_on_error is not set or the error is not one
1343+
# of the specified error types, raise it
1344+
if (
1345+
conn.retry_on_error is None
1346+
or isinstance(error, tuple(conn.retry_on_error)) is False
1347+
):
13361348
self.reset()
13371349
raise
13381350

@@ -1490,11 +1502,15 @@ def load_scripts(self):
14901502
if not exist:
14911503
s.sha = immediate("SCRIPT LOAD", s.script)
14921504

1493-
def _disconnect_raise_reset(self, conn: Redis, error: Exception) -> None:
1505+
def _disconnect_raise_reset(
1506+
self,
1507+
conn: AbstractConnection,
1508+
error: Exception,
1509+
) -> None:
14941510
"""
14951511
Close the connection, raise an exception if we were watching,
1496-
and raise an exception if TimeoutError is not part of retry_on_error,
1497-
or the error is not a TimeoutError
1512+
and raise an exception if retry_on_error is not set or the
1513+
error is not one of the specified error types.
14981514
"""
14991515
conn.disconnect()
15001516
# if we were watching a variable, the watch is no longer valid
@@ -1504,11 +1520,13 @@ def _disconnect_raise_reset(self, conn: Redis, error: Exception) -> None:
15041520
raise WatchError(
15051521
"A ConnectionError occurred on while watching one or more keys"
15061522
)
1507-
# if TimeoutError is not part of retry_on_error, or the error
1508-
# is not a TimeoutError, raise it
1509-
if not (
1510-
TimeoutError in conn.retry_on_error and isinstance(error, TimeoutError)
1523+
# if retry_on_error is not set or the error is not one
1524+
# of the specified error types, raise it
1525+
if (
1526+
conn.retry_on_error is None
1527+
or isinstance(error, tuple(conn.retry_on_error)) is False
15111528
):
1529+
15121530
self.reset()
15131531
raise error
15141532

0 commit comments

Comments
 (0)