Skip to content

Commit

Permalink
Make disconnect_on_error optional for Connection.read_response()
Browse files Browse the repository at this point in the history
  • Loading branch information
kristjanvalur committed Dec 15, 2022
1 parent 8cbd128 commit 7dccb43
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 16 deletions.
4 changes: 3 additions & 1 deletion redis/asyncio/client.py
Expand Up @@ -781,7 +781,9 @@ async def parse_response(self, block: bool = True, timeout: float = 0):
await conn.connect()

read_timeout = None if block else timeout
response = await self._execute(conn, conn.read_response, timeout=read_timeout)
response = await self._execute(
conn, conn.read_response, timeout=read_timeout, disconnect_on_error=False
)

if conn.health_check_interval and response == self.health_check_response:
# ignore the health check message as user might not expect it
Expand Down
21 changes: 12 additions & 9 deletions redis/asyncio/connection.py
Expand Up @@ -787,6 +787,7 @@ async def read_response(
self,
disable_decoding: bool = False,
timeout: Optional[float] = None,
disconnect_on_error: bool = True,
):
"""Read the response from a previously sent command"""
read_timeout = timeout if timeout is not None else self.socket_timeout
Expand All @@ -802,22 +803,24 @@ async def read_response(
)
except asyncio.TimeoutError:
if timeout is not None:
# user requested timeout, return None
# user requested timeout, return None. Operation can be retried
return None
# it was a self.socket_timeout error.
await self.disconnect(nowait=True)
if disconnect_on_error:
await self.disconnect(nowait=True)
raise TimeoutError(f"Timeout reading from {self.host}:{self.port}")
except OSError as e:
await self.disconnect(nowait=True)
if disconnect_on_error:
await self.disconnect(nowait=True)
raise ConnectionError(
f"Error while reading from {self.host}:{self.port} : {e.args}"
)
except asyncio.CancelledError:
# need this check for 3.7, where CancelledError
# is subclass of Exception, not BaseException
raise
except Exception:
await self.disconnect(nowait=True)
except BaseException:
# Also by default close in case of BaseException. A lot of code
# relies on this behaviour when doing Command/Response pairs.
# See #1128.
if disconnect_on_error:
await self.disconnect(nowait=True)
raise

if self.health_check_interval:
Expand Down
2 changes: 1 addition & 1 deletion redis/client.py
Expand Up @@ -1526,7 +1526,7 @@ def try_read():
return None
else:
conn.connect()
return conn.read_response()
return conn.read_response(disconnect_on_error=False)

response = self._execute(conn, try_read)

Expand Down
16 changes: 11 additions & 5 deletions redis/connection.py
Expand Up @@ -801,7 +801,7 @@ def can_read(self, timeout=0):
f"Error while reading from {self.host}:{self.port}: {e.args}"
)

def read_response(self, disable_decoding=False):
def read_response(self, disable_decoding=False, disconnect_on_error: bool = True):
"""Read the response from a previously sent command"""
try:
hosterr = f"{self.host}:{self.port}"
Expand All @@ -811,13 +811,19 @@ def read_response(self, disable_decoding=False):
try:
response = self._parser.read_response(disable_decoding=disable_decoding)
except socket.timeout:
self.disconnect()
if disconnect_on_error:
self.disconnect()
raise TimeoutError(f"Timeout reading from {hosterr}")
except OSError as e:
self.disconnect()
if disconnect_on_error:
self.disconnect()
raise ConnectionError(f"Error while reading from {hosterr}" f" : {e.args}")
except Exception:
self.disconnect()
except BaseException:
# Also by default close in case of BaseException. A lot of code
# relies on this behaviour when doing Command/Response pairs.
# See #1128.
if disconnect_on_error:
self.disconnect()
raise

if self.health_check_interval:
Expand Down

0 comments on commit 7dccb43

Please sign in to comment.