Skip to content

Commit 083c247

Browse files
committed
PYTHON-2055 Subtract message header from compressed bulk OP_MSG
This change prevents pymongo from generating a bulk OP_COMPRESSED/OP_MSG with an uncompressed message larger than the server's limit of maxMessageSizeBytes - 16.
1 parent 1fdfb98 commit 083c247

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

pymongo/message.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,9 @@ def max_bson_size(self):
922922
@property
923923
def max_message_size(self):
924924
"""A proxy for SockInfo.max_message_size."""
925+
if self.compress:
926+
# Subtract 16 bytes for the message header.
927+
return self.sock_info.max_message_size - 16
925928
return self.sock_info.max_message_size
926929

927930
@property

test/test_bulk.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,24 @@ def test_numerous_inserts(self):
308308
self.assertEqual(n_docs, result.inserted_count)
309309
self.assertEqual(n_docs, self.coll.count_documents({}))
310310

311+
@client_context.require_version_min(3, 6)
312+
def test_bulk_max_message_size(self):
313+
self.coll.delete_many({})
314+
self.addCleanup(self.coll.delete_many, {})
315+
_16_MB = 16 * 1000 * 1000
316+
# Generate a list of documents such that the first batched OP_MSG is
317+
# as close as possible to the 48MB limit.
318+
docs = [
319+
{'_id': 1, 'l': 's' * _16_MB},
320+
{'_id': 2, 'l': 's' * _16_MB},
321+
{'_id': 3, 'l': 's' * (_16_MB - 10000)},
322+
]
323+
# Fill in the remaining ~10000 bytes with small documents.
324+
for i in range(4, 10000):
325+
docs.append({'_id': i})
326+
result = self.coll.insert_many(docs)
327+
self.assertEqual(len(docs), len(result.inserted_ids))
328+
311329
def test_generator_insert(self):
312330
def gen():
313331
yield {'a': 1, 'b': 1}

0 commit comments

Comments
 (0)