Skip to content

Commit 9e2ff81

Browse files
author
Zhen
committed
Fix the bug related to buffer resize
Still cannot locate where is the problem. Failed to reproduce it with a unit test. The guess of the cause of bug is related to reading a big chunk that cannot be fit in buffer after the first INIT message. It seems INIT might hold a reference to a memory view somewhere.
1 parent a1ab6ce commit 9e2ff81

File tree

4 files changed

+20
-3
lines changed

4 files changed

+20
-3
lines changed

neo4j/bolt/_io.pyx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ cdef class MessageFrame(object):
101101
value.extend(self.read(n - (end - start)))
102102
return value
103103

104+
cpdef close(self):
105+
self._view = None
106+
104107

105108
cdef class ChunkedInputBuffer(object):
106109

@@ -245,6 +248,7 @@ cdef class ChunkedInputBuffer(object):
245248

246249
cpdef discard_message(self):
247250
if self._frame is not None:
251+
self._frame.close()
248252
self._origin = self._limit
249253
self._limit = -1
250254
self._frame = None

neo4j/bolt/connection.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,11 @@ def __init__(self, address, sock, error_handler, **config):
170170
self.socket = sock
171171
self.error_handler = error_handler
172172
self.server = ServerInfo(SocketAddress.from_socket(sock))
173-
self.input_buffer = ChunkedInputBuffer()
173+
input_buffer_size = config.get("default_read_buffer_size")
174+
if input_buffer_size:
175+
self.input_buffer = ChunkedInputBuffer(capacity=input_buffer_size)
176+
else:
177+
self.input_buffer = ChunkedInputBuffer()
174178
self.output_buffer = ChunkedOutputBuffer()
175179
self.packer = Packer(self.output_buffer)
176180
self.unpacker = Unpacker()

neo4j/bolt/io.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ def read(self, n):
8383
value.extend(self.read(n - (end - start)))
8484
return value
8585

86+
def close(self):
87+
self._view = None
88+
8689

8790
class ChunkedInputBuffer(object):
8891

@@ -200,6 +203,7 @@ def frame_message(self):
200203

201204
def discard_message(self):
202205
if self._frame is not None:
206+
self._frame.close()
203207
self._origin = self._limit
204208
self._limit = -1
205209
self._frame = None

test/integration/test_session.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,11 @@
2323
from neo4j.v1 import \
2424
READ_ACCESS, WRITE_ACCESS, \
2525
CypherError, SessionError, TransactionError, \
26-
Node, Relationship, Path
26+
Node, Relationship, Path, GraphDatabase
2727
from neo4j.exceptions import CypherSyntaxError
2828

2929
from test.integration.tools import DirectIntegrationTestCase
3030

31-
3231
class AutoCommitTransactionTestCase(DirectIntegrationTestCase):
3332

3433
def test_can_run_simple_statement(self):
@@ -459,6 +458,12 @@ def test_errors_on_begin_transaction(self):
459458
with self.assertRaises(SessionError):
460459
session.begin_transaction()
461460

461+
def test_large_values(self):
462+
driver = GraphDatabase.driver(self.bolt_uri, auth=self.auth_token, default_read_buffer_size=16)
463+
session = driver.session()
464+
session.run("RETURN '{}'".format("A" * 251172))
465+
session.close()
466+
driver.close()
462467

463468
class TransactionCommittedTestCase(DirectIntegrationTestCase):
464469

0 commit comments

Comments
 (0)