Skip to content

Commit 711f4a6

Browse files
authored
Fix frame reader (#436)
In the frame reader, we were storing the frame size including the header (frame size + flags which is 6 bytes). Also, after reading the frame size from the header, we were incrementing the bytes_read. That approach works for small frames, that we can read with one go, but was not working for frames that are large. For the same frame, the next time we call read_frame, the length of the reader (the data we haven't read from the buffer) was equal to frame size, but the variable frame_size was equal to `frame_size + HEADER_SIZE`. So, we were not reading the data that was actually there due to some faulty length check. We were able to read the data that is in the buffer after some long time, when the response for the client ping request comes as it was incrementing the length of the reader enough to pass the length check. To fix that, now, the frame_size field holds the frame size excluding the header size.
1 parent 6e860c2 commit 711f4a6

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

hazelcast/connection.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,8 @@ def __init__(self, builder):
693693
self._builder = builder
694694
self._bytes_read = 0
695695
self._bytes_written = 0
696-
self._frame_size = 0
696+
# Size of the frame excluding the header (SIZE_OF_FRAME_LENGTH_AND_FLAGS bytes)
697+
self._frame_size = -1
697698
self._frame_flags = 0
698699
self._message = None
699700

@@ -719,22 +720,21 @@ def _read_message(self):
719720
return None
720721

721722
def _read_frame(self):
722-
n = self.length
723-
if n < SIZE_OF_FRAME_LENGTH_AND_FLAGS:
724-
# we don't have even the frame length and flags ready
725-
return False
723+
if self._frame_size == -1:
724+
if self.length < SIZE_OF_FRAME_LENGTH_AND_FLAGS:
725+
# we don't have even the frame length and flags ready
726+
return False
726727

727-
if self._frame_size == 0:
728728
self._read_frame_size_and_flags()
729729

730-
if n < self._frame_size:
730+
if self.length < self._frame_size:
731731
return False
732732

733733
self._buf.seek(self._bytes_read)
734-
size = self._frame_size - SIZE_OF_FRAME_LENGTH_AND_FLAGS
734+
size = self._frame_size
735735
data = self._buf.read(size)
736736
self._bytes_read += size
737-
self._frame_size = 0
737+
self._frame_size = -1
738738
# No need to reset flags since it will be overwritten on the next read_frame_size_and_flags call
739739
frame = Frame(data, self._frame_flags)
740740
if not self._message:
@@ -747,6 +747,7 @@ def _read_frame_size_and_flags(self):
747747
self._buf.seek(self._bytes_read)
748748
header_data = self._buf.read(SIZE_OF_FRAME_LENGTH_AND_FLAGS)
749749
self._frame_size, self._frame_flags = _frame_header.unpack_from(header_data, 0)
750+
self._frame_size -= SIZE_OF_FRAME_LENGTH_AND_FLAGS
750751
self._bytes_read += SIZE_OF_FRAME_LENGTH_AND_FLAGS
751752

752753
def _reset(self):

tests/integration/backward_compatible/proxy/map_test.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@
1111
write_string_to_output,
1212
read_string_from_input,
1313
)
14-
from tests.util import random_string, event_collector, fill_map, is_server_version_older_than
14+
from tests.util import (
15+
random_string,
16+
event_collector,
17+
fill_map,
18+
is_server_version_older_than,
19+
get_current_timestamp,
20+
)
1521
from hazelcast import six
1622
from hazelcast.six.moves import range
1723

@@ -396,6 +402,13 @@ def test_put_get(self):
396402
self.assertIsNone(self.map.put("key", "value"))
397403
self.assertEqual(self.map.get("key"), "value")
398404

405+
def test_put_get_large_payload(self):
406+
payload = bytearray(os.urandom(16 * 1024 * 1024))
407+
start = get_current_timestamp()
408+
self.assertIsNone(self.map.put("key", payload))
409+
self.assertEqual(self.map.get("key"), payload)
410+
self.assertLessEqual(get_current_timestamp() - start, 5)
411+
399412
def test_put_get2(self):
400413
val = "x" * 5000
401414

0 commit comments

Comments
 (0)