Skip to content

Commit 5cc0704

Browse files
committed
make can_read() destructive for simplicity, and rename the method.
Remove timeout argument, always timeout immediately.
1 parent 3cdb3cc commit 5cc0704

File tree

3 files changed

+18
-33
lines changed

3 files changed

+18
-33
lines changed

redis/asyncio/connection.py

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ def on_disconnect(self):
197197
def on_connect(self, connection: "Connection"):
198198
raise NotImplementedError()
199199

200-
async def can_read(self, timeout: float) -> bool:
200+
async def can_read_destructive(self) -> bool:
201201
raise NotImplementedError()
202202

203203
async def read_response(
@@ -275,9 +275,9 @@ async def _read_from_socket(
275275
return False
276276
raise ConnectionError(f"Error while reading from socket: {ex.args}")
277277

278-
async def can_read(self, timeout: float) -> bool:
278+
async def can_read_destructive(self) -> bool:
279279
return bool(self.length) or await self._read_from_socket(
280-
timeout=timeout, raise_on_timeout=False
280+
timeout=0, raise_on_timeout=False
281281
)
282282

283283
async def read(self, length: int) -> bytes:
@@ -375,8 +375,8 @@ def on_disconnect(self):
375375
self._buffer = None
376376
self.encoder = None
377377

378-
async def can_read(self, timeout: float):
379-
return self._buffer and bool(await self._buffer.can_read(timeout))
378+
async def can_read_destructive(self):
379+
return self._buffer and bool(await self._buffer.can_read_destructive())
380380

381381
async def read_response(
382382
self, disable_decoding: bool = False
@@ -433,9 +433,7 @@ async def read_response(
433433
class HiredisParser(BaseParser):
434434
"""Parser class for connections using Hiredis"""
435435

436-
__slots__ = BaseParser.__slots__ + ("_next_response", "_reader", "_socket_timeout")
437-
438-
_next_response: bool
436+
__slots__ = BaseParser.__slots__ + ("_reader", "_socket_timeout")
439437

440438
def __init__(self, socket_read_size: int):
441439
if not HIREDIS_AVAILABLE:
@@ -455,23 +453,18 @@ def on_connect(self, connection: "Connection"):
455453
kwargs["errors"] = connection.encoder.encoding_errors
456454

457455
self._reader = hiredis.Reader(**kwargs)
458-
self._next_response = False
459456
self._socket_timeout = connection.socket_timeout
460457

461458
def on_disconnect(self):
462459
self._stream = None
463460
self._reader = None
464-
self._next_response = False
465461

466-
async def can_read(self, timeout: float):
462+
async def can_read_destructive(self):
467463
if not self._stream or not self._reader:
468464
raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR)
469-
470-
if self._next_response is False:
471-
self._next_response = self._reader.gets()
472-
if self._next_response is False:
473-
return await self.read_from_socket(timeout=timeout, raise_on_timeout=False)
474-
return True
465+
if self._reader.gets():
466+
return True
467+
return await self.read_from_socket(timeout=0, raise_on_timeout=False)
475468

476469
async def read_from_socket(
477470
self,
@@ -514,12 +507,6 @@ async def read_response(
514507
self.on_disconnect()
515508
raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR) from None
516509

517-
# _next_response might be cached from a can_read() call
518-
if self._next_response is not False:
519-
response = self._next_response
520-
self._next_response = False
521-
return response
522-
523510
response = self._reader.gets()
524511
while response is False:
525512
await self.read_from_socket()
@@ -916,12 +903,10 @@ async def send_command(self, *args: Any, **kwargs: Any) -> None:
916903
self.pack_command(*args), check_health=kwargs.get("check_health", True)
917904
)
918905

919-
async def can_read(self, timeout: float = 0):
906+
async def can_read_destructive(self):
920907
"""Poll the socket to see if there's data that can be read."""
921-
if not self.is_connected:
922-
await self.connect()
923908
try:
924-
return await self._parser.can_read(timeout)
909+
return await self._parser.can_read_destructive()
925910
except OSError as e:
926911
await self.disconnect()
927912
raise ConnectionError(
@@ -1523,12 +1508,12 @@ async def get_connection(self, command_name, *keys, **options):
15231508
# pool before all data has been read or the socket has been
15241509
# closed. either way, reconnect and verify everything is good.
15251510
try:
1526-
if await connection.can_read():
1511+
if await connection.can_read_destructive():
15271512
raise ConnectionError("Connection has data") from None
15281513
except ConnectionError:
15291514
await connection.disconnect()
15301515
await connection.connect()
1531-
if await connection.can_read():
1516+
if await connection.can_read_destructive():
15321517
raise ConnectionError("Connection not ready") from None
15331518
except BaseException:
15341519
# release the connection back to the pool so that we don't
@@ -1724,12 +1709,12 @@ async def get_connection(self, command_name, *keys, **options):
17241709
# pool before all data has been read or the socket has been
17251710
# closed. either way, reconnect and verify everything is good.
17261711
try:
1727-
if await connection.can_read():
1712+
if await connection.can_read_destructive():
17281713
raise ConnectionError("Connection has data") from None
17291714
except ConnectionError:
17301715
await connection.disconnect()
17311716
await connection.connect()
1732-
if await connection.can_read():
1717+
if await connection.can_read_destructive():
17331718
raise ConnectionError("Connection not ready") from None
17341719
except BaseException:
17351720
# release the connection back to the pool so that we don't leak it

tests/test_asyncio/test_connection_pool.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ async def connect(self):
103103
async def disconnect(self):
104104
pass
105105

106-
async def can_read(self, timeout: float = 0):
106+
async def can_read_destructive(self, timeout: float = 0):
107107
return False
108108

109109

tests/test_asyncio/test_pubsub.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,7 @@ async def test_reconnect_socket_error(self, r: redis.Redis, method):
842842
self.state = 1
843843
with mock.patch.object(self.pubsub.connection, "_parser") as mockobj:
844844
mockobj.read_response.side_effect = socket.error
845-
mockobj.can_read.side_effect = socket.error
845+
mockobj.can_read_destructive.side_effect = socket.error
846846
# wait until task noticies the disconnect until we undo the patch
847847
await self.cond.wait_for(lambda: self.state >= 2)
848848
assert not self.pubsub.connection.is_connected

0 commit comments

Comments
 (0)