76
76
77
77
class PyMongoProtocol (asyncio .BufferedProtocol ):
78
78
def __init__ (self ):
79
+ self ._buffer_size = MAX_MESSAGE_SIZE
79
80
self .transport = None
80
- self ._buffer = memoryview (bytearray (MAX_MESSAGE_SIZE ))
81
+ self ._buffer = memoryview (bytearray (self . _buffer_size ))
81
82
self .expected_length = 0
82
83
self .expecting_header = False
83
84
self .ready_offset = 0
@@ -118,13 +119,15 @@ async def read(self):
118
119
def unpack_message (self , message ):
119
120
start , end , opcode = message .result ()
120
121
if isinstance (start , tuple ):
122
+ # print(f"Unpacking message with start {start} and end {end} on {asyncio.current_task()}")
121
123
return memoryview (
122
- self ._buffer [start [0 ]:end [0 ]]. tobytes ( ) + self ._buffer [start [1 ]:end [1 ]]. tobytes ( )), opcode
124
+ bytearray ( self ._buffer [start [0 ]:end [0 ]]) + bytearray ( self ._buffer [start [1 ]:end [1 ]])), opcode
123
125
else :
124
126
return self ._buffer [start :end ], opcode
125
127
126
128
def get_buffer (self , sizehint : int ):
127
- if self .empty_offset + sizehint >= MAX_MESSAGE_SIZE - 1 :
129
+ # print(f"get_buffer with empty {self.empty_offset} and sizehint {sizehint}, ready {self.ready_offset}")
130
+ if self .empty_offset + sizehint >= self ._buffer_size :
128
131
self .empty_offset = 0
129
132
if self .empty_offset < self .ready_offset :
130
133
return self ._buffer [self .empty_offset :self .ready_offset ]
@@ -139,18 +142,25 @@ def buffer_updated(self, nbytes: int):
139
142
if self .expecting_header :
140
143
self .expected_length , _ , _ , self .op_code = _UNPACK_HEADER (self ._buffer [self .ready_offset :self .ready_offset + 16 ])
141
144
self .expecting_header = False
145
+ self .ready_offset += 16
146
+ self .expected_length -= 16
142
147
148
+ # print(f"Ready: {self.ready_offset} out of {self._buffer_size}")
143
149
if self .ready_offset < self .empty_offset :
144
150
if self .empty_offset - self .ready_offset >= self .expected_length :
145
- self .store_message (self .ready_offset + 16 , self .ready_offset + self .expected_length , self .op_code )
151
+ self .store_message (self .ready_offset , self .ready_offset + self .expected_length , self .op_code )
146
152
self .ready_offset += self .expected_length
147
153
else :
148
- if self .ready_offset + self .expected_length <= MAX_MESSAGE_SIZE - 1 :
149
- self .store_message (self .ready_offset + 16 , self .ready_offset + self .expected_length , self .op_code )
154
+ # print(f"Ready: {self.ready_offset}, Empty: {self.empty_offset}, expecting: {self.expected_length}")
155
+ # print(f"Is linear: {self.ready_offset + self.expected_length <= self._buffer_size}, {self.ready_offset + self.expected_length} vs {self._buffer_size}")
156
+ # print(f"Is wrapped: {self._buffer_size - self.ready_offset + self.empty_offset >= self.expected_length}, {self._buffer_size - self.ready_offset + self.empty_offset} vs {self.expected_length}")
157
+ if self .ready_offset + self .expected_length <= self ._buffer_size :
158
+ self .store_message (self .ready_offset , self .ready_offset + self .expected_length , self .op_code )
150
159
self .ready_offset += self .expected_length
151
- elif MAX_MESSAGE_SIZE - 1 - self .ready_offset + self .empty_offset >= self .expected_length :
152
- self .store_message ((self .ready_offset , 0 ), (MAX_MESSAGE_SIZE - 1 , self .expected_length - (MAX_MESSAGE_SIZE - 1 - self .ready_offset )), self .op_code )
153
- self .ready_offset = self .expected_length - (MAX_MESSAGE_SIZE - 1 - self .ready_offset )
160
+ elif self ._buffer_size - self .ready_offset + self .empty_offset >= self .expected_length :
161
+ # print(f"{asyncio.current_task()} First chunk: {self._buffer_size - self.ready_offset}, second chunk: {self.expected_length - (self._buffer_size - self.ready_offset)}, total: {self._buffer_size - self.ready_offset + self.expected_length - (self._buffer_size - self.ready_offset)} of {self.expected_length}")
162
+ self .store_message ((self .ready_offset , 0 ), (self ._buffer_size , self .expected_length - (self ._buffer_size - self .ready_offset )), self .op_code )
163
+ self .ready_offset = self .expected_length - (self ._buffer_size - self .ready_offset )
154
164
155
165
def store_message (self , start , end , opcode ):
156
166
stored = False
0 commit comments