From 118a48d84e662c4189e67c331287f3f21b5c9465 Mon Sep 17 00:00:00 2001 From: xXenvy Date: Fri, 3 May 2024 21:32:43 +0200 Subject: [PATCH 01/11] refactor: change socket data reception check using end marker --- zcached/client.py | 24 ++++++++++++------------ zcached/connection.py | 41 +++++++++++++++++++++-------------------- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/zcached/client.py b/zcached/client.py index aa697b3..0a0cde9 100644 --- a/zcached/client.py +++ b/zcached/client.py @@ -73,27 +73,27 @@ def run(self) -> None: def ping(self) -> Result[str]: """Send a ping command to the database.""" - return self.connection.send(b"*1\r\n$4\r\nPING\r\n") + return self.connection.send(b"*1\r\n$4\r\nPING\r\n\x04") def flush(self) -> Result[str]: """Method to flush all database records.""" - return self.connection.send(b"*1\r\n$5\r\nFLUSH\r\n") + return self.connection.send(b"*1\r\n$5\r\nFLUSH\r\n\x04") def dbsize(self) -> Result[int]: """Retrieve the size of the database.""" - return self.connection.send(b"*1\r\n$6\r\nDBSIZE\r\n") + return self.connection.send(b"*1\r\n$6\r\nDBSIZE\r\n\x04") def save(self) -> Result[str]: """Method to save all database records.""" - return self.connection.send(b"*1\r\n$4\r\nSAVE\r\n") + return self.connection.send(b"*1\r\n$4\r\nSAVE\r\n\x04") def keys(self) -> Result[List[str]]: """Retrieve the keys of the database.""" - return self.connection.send(b"*1\r\n$4\r\nKEYS\r\n") + return self.connection.send(b"*1\r\n$4\r\nKEYS\r\n\x04") def lastsave(self) -> Result[int]: """Method to retrieve the Unix timestamp of the last successful database save.""" - return self.connection.send(b"*1\r\n$8\r\nLASTSAVE\r\n") + return self.connection.send(b"*1\r\n$8\r\nLASTSAVE\r\n\x04") def get(self, key: str) -> Result: """ @@ -104,7 +104,7 @@ def get(self, key: str) -> Result: key: The key to retrieve the value from the database. """ - command: str = f"*2\r\n$3\r\nGET\r\n${len(key)}\r\n{key}\r\n" + command: str = f"*2\r\n$3\r\nGET\r\n${len(key)}\r\n{key}\r\n\x04" return self.connection.send(command.encode()) def mget(self, *keys: str) -> Result[dict[str, Any]]: @@ -127,7 +127,7 @@ def mget(self, *keys: str) -> Result[dict[str, Any]]: for key in keys: command += f"${len(key)}\r\n{key}\r\n" - return self.connection.send(command.encode()) + return self.connection.send((command + "\x04").encode()) def set(self, key: str, value: SupportedTypes) -> Result[str]: """ @@ -141,9 +141,9 @@ def set(self, key: str, value: SupportedTypes) -> Result[str]: The value of the record. """ command: str = ( - f"*3\r\n$3\r\nSET\r\n${len(key)}\r\n{key}\r\n{self._serializer.process(value)}" + f"*3\r\n$3\r\nSET\r\n${len(key)}\r\n{key}\r\n{self._serializer.process(value)}\x04" ) - return self.connection.send(command.encode()) + return self.connection.send((command + "\x04").encode()) def mset(self, **params: SupportedTypes) -> Result[str]: """ @@ -160,7 +160,7 @@ def mset(self, **params: SupportedTypes) -> Result[str]: for key, value in params.items(): command += f"${len(key)}\r\n{key}\r\n{self._serializer.process(value)}" - return self.connection.send(command.encode()) + return self.connection.send((command + "\x04").encode()) def delete(self, key: str) -> Result[str]: """ @@ -171,7 +171,7 @@ def delete(self, key: str) -> Result[str]: key: Key of the record being deleted. """ - command: str = f"*2\r\n$6\r\nDELETE\r\n${len(key)}\r\n{key}\r\n" + command: str = f"*2\r\n$6\r\nDELETE\r\n${len(key)}\r\n{key}\r\n\x04" return self.connection.send(command.encode()) def exists(self, key: str) -> bool: diff --git a/zcached/connection.py b/zcached/connection.py index 92665d0..6345bc6 100644 --- a/zcached/connection.py +++ b/zcached/connection.py @@ -205,39 +205,31 @@ def wait_for_response(self) -> Result: NOT THREAD SAFE. """ backoff: ExponentialBackoff = ExponentialBackoff(0.1, 1.5, 0.5) - total_bytes: bytes = bytes() - transfer_complete: bool = False + + # Without this, the backoff will have to wait on the first iteration. + sleep(0.01) for timeout in backoff: data: bytes | None = self.receive() if not isinstance(data, bytes): - if len(total_bytes) > 0: - # If we already have some data, and this iteration gave us None, - # it means that the data transfer has been completed. - transfer_complete = True + if len(total_bytes) >= 1: + logging.debug("Received incomplete data. Awaiting for the rest.") else: # We haven't received any data yet. logging.debug( f"There is no data in the socket. Timeout: {timeout}s." ) - if backoff.total >= float(self.timeout_limit): - logging.error( - "The waiting time limit for a response has been reached." - ) - return Result.fail(Errors.TimeoutLimit.value) - sleep(timeout) - continue - - if transfer_complete: - # If the first byte is "-", it means that the response is an error. - if total_bytes.startswith(b"-"): - error_message: str = total_bytes.decode()[1::] - return Result.fail(error_message.replace("\r\n", "")) + if backoff.total >= float(self.timeout_limit): + logging.error( + "The waiting time limit for a response has been reached." + ) + return Result.fail(Errors.TimeoutLimit.value) - return Result.ok(total_bytes) + sleep(timeout) + continue if len(data) == 0: # type: ignore # When socket lose connection to the server it receives empty bytes. @@ -245,6 +237,15 @@ def wait_for_response(self) -> Result: total_bytes += data # type: ignore + if total_bytes.endswith(b'\x04'): # Received complete data. + + # If the first byte is "-", it means that the response is an error. + if total_bytes.startswith(b"-"): + error_message: str = total_bytes[1:-1].decode() + return Result.fail(error_message.replace("\r\n", "")) + + return Result.ok(total_bytes[:-1]) + # ExponentialBackoff should be increased only when we receive None. backoff.reset() From 6624c504f363c4c109d0c93133bbbab002adbc2f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 3 May 2024 19:36:16 +0000 Subject: [PATCH 02/11] style: auto fixes from pre-commit hooks --- zcached/connection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zcached/connection.py b/zcached/connection.py index 6345bc6..f821d32 100644 --- a/zcached/connection.py +++ b/zcached/connection.py @@ -237,7 +237,7 @@ def wait_for_response(self) -> Result: total_bytes += data # type: ignore - if total_bytes.endswith(b'\x04'): # Received complete data. + if total_bytes.endswith(b"\x04"): # Received complete data. # If the first byte is "-", it means that the response is an error. if total_bytes.startswith(b"-"): From a03814e7e9e0aa64a985cb6afc624e3aa405a771 Mon Sep 17 00:00:00 2001 From: xXenvy Date: Fri, 3 May 2024 21:46:20 +0200 Subject: [PATCH 03/11] style: remove unnecessary space --- zcached/connection.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/zcached/connection.py b/zcached/connection.py index f821d32..1d82213 100644 --- a/zcached/connection.py +++ b/zcached/connection.py @@ -159,7 +159,6 @@ def send(self, data: bytes) -> Result: logging.debug("Waiting for the thread lock to become available.") with self._lock: - try: logging.debug("Sending data to the server -> %s", data) self.socket.send(data) @@ -199,11 +198,7 @@ def try_reconnect(self) -> Result[bytes]: return Result.fail(Errors.ConnectionClosed.value) def wait_for_response(self) -> Result: - """ - A loop to wait for the response from the server. - - NOT THREAD SAFE. - """ + """A loop to wait for the response from the server.""" backoff: ExponentialBackoff = ExponentialBackoff(0.1, 1.5, 0.5) total_bytes: bytes = bytes() From 326d9af80cc7f8782ee24501d81353a1286e2617 Mon Sep 17 00:00:00 2001 From: xXenvy Date: Fri, 3 May 2024 21:53:51 +0200 Subject: [PATCH 04/11] refactor: remove replace "\r\n" --- zcached/connection.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zcached/connection.py b/zcached/connection.py index 1d82213..8561b80 100644 --- a/zcached/connection.py +++ b/zcached/connection.py @@ -236,8 +236,8 @@ def wait_for_response(self) -> Result: # If the first byte is "-", it means that the response is an error. if total_bytes.startswith(b"-"): - error_message: str = total_bytes[1:-1].decode() - return Result.fail(error_message.replace("\r\n", "")) + error_message: str = total_bytes[1:-3].decode() + return Result.fail(error_message) return Result.ok(total_bytes[:-1]) From 28de1c1c52e5ad449bc41251848fdcae24482016 Mon Sep 17 00:00:00 2001 From: xXenvy Date: Fri, 17 May 2024 00:51:02 +0200 Subject: [PATCH 05/11] feat(connection): read until '\x04' sign --- zcached/asyncio/connection.py | 7 +++--- zcached/connection.py | 40 ++++++++++------------------------- zcached/enums.py | 22 +++++++++---------- 3 files changed, 25 insertions(+), 44 deletions(-) diff --git a/zcached/asyncio/connection.py b/zcached/asyncio/connection.py index 8e4d015..b58b306 100644 --- a/zcached/asyncio/connection.py +++ b/zcached/asyncio/connection.py @@ -221,8 +221,10 @@ async def send(self, data: bytes) -> Result: logger.debug(f"{self.id} -> The connection has been terminated.") if not self.reconnect: return Result.fail(Errors.ConnectionClosed.value) - return await self.try_reconnect() + finally: + if self._pending_requests >= 1: + self._pending_requests -= 1 result: Result = await self.wait_for_response() if self.reconnect and result.error == Errors.ConnectionClosed: @@ -293,9 +295,6 @@ async def wait_for_response(self) -> Result: complete_data += data - if self._pending_requests >= 1: - self._pending_requests -= 1 - # If the first byte is "-", it means that the response is an error. if complete_data.startswith(b"-"): error_message: str = complete_data.decode()[1:-2] diff --git a/zcached/connection.py b/zcached/connection.py index ff47963..d1a4365 100644 --- a/zcached/connection.py +++ b/zcached/connection.py @@ -192,8 +192,10 @@ def send(self, data: bytes) -> Result: except (BrokenPipeError, OSError): if not self.reconnect: return Result.fail(Errors.ConnectionClosed.value) - return self.try_reconnect() + finally: + if self._pending_requests >= 1: + self._pending_requests -= 1 result: Result = self.wait_for_response() if not self.reconnect or result.error is None: @@ -226,41 +228,22 @@ def try_reconnect(self) -> Result[bytes]: def wait_for_response(self) -> Result: """A loop to wait for the response from the server.""" - backoff: ExponentialBackoff = ExponentialBackoff(0.1, 1.5, 0.5) + backoff: ExponentialBackoff = ExponentialBackoff(0.01, 3, 0.5) total_bytes: bytes = bytes() - # Without this, the backoff will have to wait on the first iteration. + # By doing this, we should receive the data at the first recv, without waiting for the backoff. sleep(0.01) for timeout in backoff: data: bytes | None = self.receive() if not isinstance(data, bytes): - if len(total_bytes) >= 1: - logging.debug("Received incomplete data. Awaiting for the rest.") - else: - # We haven't received any data yet. - logging.debug( - f"{self.id} -> There is no data in the socket. Timeout: {timeout}s." - ) - if backoff.total >= float(self.timeout_limit): - logging.error( - f"{self.id} -> The waiting time limit for a response has been reached." - ) - return Result.fail(Errors.TimeoutLimit.value) - - sleep(timeout) - continue - - if transfer_complete: - if self._pending_requests >= 1: - self._pending_requests -= 1 - - # If the first byte is "-", it means that the response is an error. - if total_bytes.startswith(b"-"): - error_message: str = total_bytes.decode()[1:-2] - return Result.fail(error_message) + if backoff.total >= self.timeout_limit: + return Result.fail(Errors.TimeoutLimit.value) + logging.debug( + f"{self.id} -> There is no data in the socket. Timeout: {timeout}s." + ) sleep(timeout) continue @@ -271,10 +254,9 @@ def wait_for_response(self) -> Result: total_bytes += data # type: ignore if total_bytes.endswith(b"\x04"): # Received complete data. - # If the first byte is "-", it means that the response is an error. if total_bytes.startswith(b"-"): - error_message: str = total_bytes[1:-3].decode() + error_message: str = total_bytes.decode()[1:-3] return Result.fail(error_message) return Result.ok(total_bytes[:-1]) diff --git a/zcached/enums.py b/zcached/enums.py index 1ce95fe..9198c61 100644 --- a/zcached/enums.py +++ b/zcached/enums.py @@ -38,16 +38,16 @@ def __repr__(self) -> str: class Commands(bytes, Enum): - PING = b"*1\r\n$4\r\nPING\r\n" - FLUSH = b"*1\r\n$5\r\nFLUSH\r\n" - DB_SIZE = b"*1\r\n$6\r\nDBSIZE\r\n" - SAVE = b"*1\r\n$4\r\nSAVE\r\n" - KEYS = b"*1\r\n$4\r\nKEYS\r\n" - LAST_SAVE = b"*1\r\n$8\r\nLASTSAVE\r\n" + PING = b"*1\r\n$4\r\nPING\r\n\x04" + FLUSH = b"*1\r\n$5\r\nFLUSH\r\n\x04" + DB_SIZE = b"*1\r\n$6\r\nDBSIZE\r\n\x04" + SAVE = b"*1\r\n$4\r\nSAVE\r\n\x04" + KEYS = b"*1\r\n$4\r\nKEYS\r\n\x04" + LAST_SAVE = b"*1\r\n$8\r\nLASTSAVE\r\n\x04" @staticmethod def get(key: str) -> bytes: - return f"*2\r\n$3\r\nGET\r\n${len(key)}\r\n{key}\r\n".encode() + return f"*2\r\n$3\r\nGET\r\n${len(key)}\r\n{key}\r\n\x04".encode() @staticmethod def mget(*keys: str) -> bytes: @@ -55,13 +55,13 @@ def mget(*keys: str) -> bytes: for key in keys: command += f"${len(key)}\r\n{key}\r\n" - return command.encode() + return (command + "\x04").encode() @staticmethod def set(key: str, value: SupportedTypes) -> bytes: serializer: Serializer = Serializer() command: str = ( - f"*3\r\n$3\r\nSET\r\n${len(key)}\r\n{key}\r\n{serializer.process(value)}" + f"*3\r\n$3\r\nSET\r\n${len(key)}\r\n{key}\r\n{serializer.process(value)}\x04" ) return command.encode() @@ -73,11 +73,11 @@ def mset(**params: SupportedTypes) -> bytes: for key, value in params.items(): command += f"${len(key)}\r\n{key}\r\n{serializer.process(value)}" - return command.encode() + return (command + "\x04").encode() @staticmethod def delete(key: str) -> bytes: - return f"*2\r\n$6\r\nDELETE\r\n${len(key)}\r\n{key}\r\n".encode() + return f"*2\r\n$6\r\nDELETE\r\n${len(key)}\r\n{key}\r\n\x04".encode() def __repr__(self) -> str: return f"{self.value}" From 4c7a828af66d4dad462c2bcf8d46150a07110eb9 Mon Sep 17 00:00:00 2001 From: xXenvy Date: Fri, 17 May 2024 01:27:14 +0200 Subject: [PATCH 06/11] feat(asyncconnection): read until '\x04' sign --- zcached/asyncio/connection.py | 36 ++++++++++++++++------------------- zcached/connection.py | 22 +++++++++++++-------- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/zcached/asyncio/connection.py b/zcached/asyncio/connection.py index b58b306..25a273c 100644 --- a/zcached/asyncio/connection.py +++ b/zcached/asyncio/connection.py @@ -270,37 +270,33 @@ async def wait_for_response(self) -> Result: NOT TASK SAFE. """ if not self._reader: + logger.error( + f"{self.id} -> Missing StreamReader object! Did you forget to connect? " + f"Aborting the wait_for_response method..." + ) return Result.fail(Errors.ConnectionClosed.value) - complete_data: bytes = bytes() - try: - data: bytes | None = await self.receive(timeout_limit=self.timeout_limit) - if data is None: - self._connected = False - return Result.fail(Errors.ConnectionClosed.value) - except asyncio.TimeoutError: - return Result.fail(Errors.TimeoutLimit.value) + total_data: bytes = bytes() - complete_data += data - - while True: + while not total_data.endswith(b"\x04"): try: - data = await self.receive(timeout_limit=0.1) + data: bytes | None = await self.receive(timeout_limit=self.timeout_limit) except asyncio.TimeoutError: - break # Transfer complete. - if data is None or len(data) == 0: - # When socket lose connection to the server it receives empty bytes. - self._connected = False + return Result.fail(Errors.TimeoutLimit.value) + + # When socket lose connection to the server it receives empty bytes. + # Or when the data is None, it means that the reader has been abandoned. + if len(data) == 0 or data is None: return Result.fail(Errors.ConnectionClosed.value) - complete_data += data + total_data += data # If the first byte is "-", it means that the response is an error. - if complete_data.startswith(b"-"): - error_message: str = complete_data.decode()[1:-2] + if total_data.startswith(b"-"): + error_message: str = total_data.decode()[1:-3] return Result.fail(error_message) - return Result.ok(complete_data) + return Result.ok(total_data[:-1]) async def close(self) -> None: """Closes the connection by closing the writer, and waiting until the writer is fully closed.""" diff --git a/zcached/connection.py b/zcached/connection.py index d1a4365..c207cbf 100644 --- a/zcached/connection.py +++ b/zcached/connection.py @@ -159,6 +159,8 @@ def receive(self) -> bytes | None: """ Method to receive the response from the server. None if there is no data in the socket yet. + + NOT THREAD SAFE. """ try: data: bytes = self.socket.recv(self.buffer_size) @@ -227,12 +229,16 @@ def try_reconnect(self) -> Result[bytes]: return Result.fail(Errors.ConnectionClosed.value) def wait_for_response(self) -> Result: - """A loop to wait for the response from the server.""" + """ + A loop to wait for the response from the server. + + NOT THREAD SAFE. + """ backoff: ExponentialBackoff = ExponentialBackoff(0.01, 3, 0.5) - total_bytes: bytes = bytes() + total_data: bytes = bytes() # By doing this, we should receive the data at the first recv, without waiting for the backoff. - sleep(0.01) + sleep(0.001) for timeout in backoff: data: bytes | None = self.receive() @@ -251,15 +257,15 @@ def wait_for_response(self) -> Result: # When socket lose connection to the server it receives empty bytes. return Result.fail(Errors.ConnectionClosed.value) - total_bytes += data # type: ignore + total_data += data # type: ignore - if total_bytes.endswith(b"\x04"): # Received complete data. + if total_data.endswith(b"\x04"): # Received complete data. # If the first byte is "-", it means that the response is an error. - if total_bytes.startswith(b"-"): - error_message: str = total_bytes.decode()[1:-3] + if total_data.startswith(b"-"): + error_message: str = total_data.decode()[1:-3] return Result.fail(error_message) - return Result.ok(total_bytes[:-1]) + return Result.ok(total_data[:-1]) # ExponentialBackoff should be increased only when we receive None. backoff.reset() From e2eb57bb1c462061d3e4f071edffff07ce71e0ec Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 23:27:27 +0000 Subject: [PATCH 07/11] style: auto fixes from pre-commit hooks --- zcached/asyncio/connection.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/zcached/asyncio/connection.py b/zcached/asyncio/connection.py index 25a273c..09df1fa 100644 --- a/zcached/asyncio/connection.py +++ b/zcached/asyncio/connection.py @@ -280,7 +280,9 @@ async def wait_for_response(self) -> Result: while not total_data.endswith(b"\x04"): try: - data: bytes | None = await self.receive(timeout_limit=self.timeout_limit) + data: bytes | None = await self.receive( + timeout_limit=self.timeout_limit + ) except asyncio.TimeoutError: return Result.fail(Errors.TimeoutLimit.value) From 758e31909344e4c2ead10e648a4edd40194cf6d2 Mon Sep 17 00:00:00 2001 From: xXenvy Date: Fri, 17 May 2024 01:28:44 +0200 Subject: [PATCH 08/11] fix: pyright --- zcached/asyncio/connection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zcached/asyncio/connection.py b/zcached/asyncio/connection.py index 09df1fa..92ba027 100644 --- a/zcached/asyncio/connection.py +++ b/zcached/asyncio/connection.py @@ -288,7 +288,7 @@ async def wait_for_response(self) -> Result: # When socket lose connection to the server it receives empty bytes. # Or when the data is None, it means that the reader has been abandoned. - if len(data) == 0 or data is None: + if data is None or len(data) == 0: # type: ignore return Result.fail(Errors.ConnectionClosed.value) total_data += data From cf34946654d24264f05cf5f8b4045980f7290331 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 17 May 2024 01:35:10 +0000 Subject: [PATCH 09/11] style: auto fixes from pre-commit hooks --- zcached/asyncio/connection.py | 4 +--- zcached/connection.py | 8 ++------ zcached/enums.py | 4 +--- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/zcached/asyncio/connection.py b/zcached/asyncio/connection.py index 68e2b2c..2d50e1a 100644 --- a/zcached/asyncio/connection.py +++ b/zcached/asyncio/connection.py @@ -274,9 +274,7 @@ async def wait_for_response(self) -> Result: while not total_data.endswith(b"\x04"): try: - data: bytes | None = await self.receive( - timeout_limit=self.timeout_limit - ) + data: bytes | None = await self.receive(timeout_limit=self.timeout_limit) except asyncio.TimeoutError: return Result.fail(Errors.TimeoutLimit.value) diff --git a/zcached/connection.py b/zcached/connection.py index f405b61..a6b7f23 100644 --- a/zcached/connection.py +++ b/zcached/connection.py @@ -180,9 +180,7 @@ def send(self, data: bytes) -> Result: Bytes to send. """ if self._lock.locked(): - logging.debug( - f"{self.id} -> Waiting for the thread lock to become available." - ) + logging.debug(f"{self.id} -> Waiting for the thread lock to become available.") with self._lock: try: @@ -244,9 +242,7 @@ def wait_for_response(self) -> Result: if backoff.total >= self.timeout_limit: return Result.fail(Errors.TimeoutLimit.value) - logging.debug( - f"{self.id} -> There is no data in the socket. Timeout: {timeout}s." - ) + logging.debug(f"{self.id} -> There is no data in the socket. Timeout: {timeout}s.") sleep(timeout) continue diff --git a/zcached/enums.py b/zcached/enums.py index abf138f..18105e1 100644 --- a/zcached/enums.py +++ b/zcached/enums.py @@ -58,9 +58,7 @@ def mget(*keys: str) -> bytes: @staticmethod def set(key: str, value: SupportedTypes) -> bytes: serializer: Serializer = Serializer() - command: str = ( - f"*3\r\n$3\r\nSET\r\n${len(key)}\r\n{key}\r\n{serializer.process(value)}\x04" - ) + command: str = f"*3\r\n$3\r\nSET\r\n${len(key)}\r\n{key}\r\n{serializer.process(value)}\x04" return command.encode() @staticmethod From c509b5bb3009487c0b9d45716b8fb60108944a60 Mon Sep 17 00:00:00 2001 From: xXenvy Date: Fri, 31 May 2024 19:35:20 +0200 Subject: [PATCH 10/11] refactor: change end char --- zcached/asyncio/connection.py | 2 +- zcached/connection.py | 2 +- zcached/enums.py | 22 +++++++++++----------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/zcached/asyncio/connection.py b/zcached/asyncio/connection.py index 92ba027..659c5d3 100644 --- a/zcached/asyncio/connection.py +++ b/zcached/asyncio/connection.py @@ -278,7 +278,7 @@ async def wait_for_response(self) -> Result: total_data: bytes = bytes() - while not total_data.endswith(b"\x04"): + while not total_data.endswith(b"\x03"): try: data: bytes | None = await self.receive( timeout_limit=self.timeout_limit diff --git a/zcached/connection.py b/zcached/connection.py index c207cbf..c555f57 100644 --- a/zcached/connection.py +++ b/zcached/connection.py @@ -259,7 +259,7 @@ def wait_for_response(self) -> Result: total_data += data # type: ignore - if total_data.endswith(b"\x04"): # Received complete data. + if total_data.endswith(b"\x03"): # Received complete data. # If the first byte is "-", it means that the response is an error. if total_data.startswith(b"-"): error_message: str = total_data.decode()[1:-3] diff --git a/zcached/enums.py b/zcached/enums.py index 9198c61..b8d979c 100644 --- a/zcached/enums.py +++ b/zcached/enums.py @@ -38,16 +38,16 @@ def __repr__(self) -> str: class Commands(bytes, Enum): - PING = b"*1\r\n$4\r\nPING\r\n\x04" - FLUSH = b"*1\r\n$5\r\nFLUSH\r\n\x04" - DB_SIZE = b"*1\r\n$6\r\nDBSIZE\r\n\x04" - SAVE = b"*1\r\n$4\r\nSAVE\r\n\x04" - KEYS = b"*1\r\n$4\r\nKEYS\r\n\x04" - LAST_SAVE = b"*1\r\n$8\r\nLASTSAVE\r\n\x04" + PING = b"*1\r\n$4\r\nPING\r\n\x03" + FLUSH = b"*1\r\n$5\r\nFLUSH\r\n\x03" + DB_SIZE = b"*1\r\n$6\r\nDBSIZE\r\n\x03" + SAVE = b"*1\r\n$4\r\nSAVE\r\n\x03" + KEYS = b"*1\r\n$4\r\nKEYS\r\n\x03" + LAST_SAVE = b"*1\r\n$8\r\nLASTSAVE\r\n\x03" @staticmethod def get(key: str) -> bytes: - return f"*2\r\n$3\r\nGET\r\n${len(key)}\r\n{key}\r\n\x04".encode() + return f"*2\r\n$3\r\nGET\r\n${len(key)}\r\n{key}\r\n\x03".encode() @staticmethod def mget(*keys: str) -> bytes: @@ -55,13 +55,13 @@ def mget(*keys: str) -> bytes: for key in keys: command += f"${len(key)}\r\n{key}\r\n" - return (command + "\x04").encode() + return (command + "\x03").encode() @staticmethod def set(key: str, value: SupportedTypes) -> bytes: serializer: Serializer = Serializer() command: str = ( - f"*3\r\n$3\r\nSET\r\n${len(key)}\r\n{key}\r\n{serializer.process(value)}\x04" + f"*3\r\n$3\r\nSET\r\n${len(key)}\r\n{key}\r\n{serializer.process(value)}\x03" ) return command.encode() @@ -73,11 +73,11 @@ def mset(**params: SupportedTypes) -> bytes: for key, value in params.items(): command += f"${len(key)}\r\n{key}\r\n{serializer.process(value)}" - return (command + "\x04").encode() + return (command + "\x03").encode() @staticmethod def delete(key: str) -> bytes: - return f"*2\r\n$6\r\nDELETE\r\n${len(key)}\r\n{key}\r\n\x04".encode() + return f"*2\r\n$6\r\nDELETE\r\n${len(key)}\r\n{key}\r\n\x03".encode() def __repr__(self) -> str: return f"{self.value}" From cc45ede35fb01973e8a0446b838e1c3203828c1f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 31 May 2024 17:35:58 +0000 Subject: [PATCH 11/11] style: auto fixes from pre-commit hooks --- zcached/enums.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/zcached/enums.py b/zcached/enums.py index 9198c61..18105e1 100644 --- a/zcached/enums.py +++ b/zcached/enums.py @@ -5,9 +5,7 @@ class Errors(str, Enum): ConnectionClosed = "The connection has been terminated." - ConnectionReestablished = ( - "The connection was terminated, but managed to reestablish it." - ) + ConnectionReestablished = "The connection was terminated, but managed to reestablish it." LibraryBug = "This is probably a library bug. Please report it here: https://github.com/xXenvy/zcached.py" TimeoutLimit = "The waiting time limit for a response has been reached." NoAvailableConnections = "No working connections available." @@ -60,9 +58,7 @@ def mget(*keys: str) -> bytes: @staticmethod def set(key: str, value: SupportedTypes) -> bytes: serializer: Serializer = Serializer() - command: str = ( - f"*3\r\n$3\r\nSET\r\n${len(key)}\r\n{key}\r\n{serializer.process(value)}\x04" - ) + command: str = f"*3\r\n$3\r\nSET\r\n${len(key)}\r\n{key}\r\n{serializer.process(value)}\x04" return command.encode() @staticmethod