diff options
author | tzickel <private@com> | 2014-06-25 23:39:00 +0300 |
---|---|---|
committer | tzickel <private@com> | 2014-06-27 20:22:19 +0300 |
commit | e03b828f083b50d46db03d5c6bf443c1fe2bfcba (patch) | |
tree | 70036e008e4f01b5c1c5c8f9e32af1c360bca13a | |
parent | bd28b48b143e736c672b90561175e85e6223c86c (diff) | |
download | redis-py-e03b828f083b50d46db03d5c6bf443c1fe2bfcba.tar.gz |
Added support for reusing a bytearray buffer when parsing with hiredis-py 0.1.4
-rwxr-xr-x | redis/connection.py | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/redis/connection.py b/redis/connection.py index f9efa7b..7018051 100755 --- a/redis/connection.py +++ b/redis/connection.py @@ -36,6 +36,8 @@ if HIREDIS_AVAILABLE: hiredis_version = StrictVersion(hiredis.__version__) HIREDIS_SUPPORTS_CALLABLE_ERRORS = \ hiredis_version >= StrictVersion('0.1.3') + HIREDIS_SUPPORTS_SANE_BUFFER = \ + hiredis_version >= StrictVersion('0.1.4') if not HIREDIS_SUPPORTS_CALLABLE_ERRORS: msg = ("redis-py works best with hiredis >= 0.1.3. You're running " @@ -262,6 +264,13 @@ class HiredisParser(BaseParser): if not HIREDIS_AVAILABLE: raise RedisError("Hiredis is not installed") self.socket_read_size = socket_read_size + self.usebuffer = True + if sys.version[0] == '2' and sys.version[2] < '7': + self.usebuffer = False + if not HIREDIS_SUPPORTS_SANE_BUFFER: + self.usebuffer = False + if self.usebuffer: + self._buffer = bytearray(socket_read_size) def __del__(self): try: @@ -312,23 +321,37 @@ class HiredisParser(BaseParser): socket_read_size = self.socket_read_size while response is False: try: - buffer = self._sock.recv(socket_read_size) - # an empty string indicates the server shutdown the socket - if isinstance(buffer, str) and len(buffer) == 0: - raise socket.error("Connection closed by remote server.") + if self.usebuffer: + bufflen = self._sock.recv_into(self._buffer) + if bufflen == 0: + raise socket.error("Connection closed by remote \ +server.") + else: + buffer = self._sock.recv(socket_read_size) + # an empty string indicates the server shutdown the socket + if isinstance(buffer, str) and len(buffer) == 0: + raise socket.error("Connection closed by remote \ +server.") except socket.timeout: raise TimeoutError("Timeout reading from socket") except socket.error: e = sys.exc_info()[1] raise ConnectionError("Error while reading from socket: %s" % (e.args,)) - if not buffer: - raise ConnectionError("Socket closed on remote end") - self._reader.feed(buffer) + if self.usebuffer: + self._reader.feed(self._buffer, 0, bufflen) + else: + if not buffer: + raise ConnectionError("Socket closed on remote end") + self._reader.feed(buffer) # proactively, but not conclusively, check if more data is in the # buffer. if the data received doesn't end with \r\n, there's more. - if not buffer.endswith(SYM_CRLF): - continue + if self.usebuffer: + if self._buffer[bufflen - 2:bufflen] != SYM_CRLF: + continue + else: + if not buffer.endswith(SYM_CRLF): + continue response = self._reader.gets() # if an older version of hiredis is installed, we need to attempt # to convert ResponseErrors to their appropriate types. |