Skip to content

Commit 6b1b509

Browse files
committed
CSHARP-2207: Large bulk writes not always splitting correctly
1 parent 13c5b9b commit 6b1b509

File tree

6 files changed

+280
-25
lines changed

6 files changed

+280
-25
lines changed

src/MongoDB.Driver.Core/Core/Misc/SizeLimitingBatchableSourceSerializer.cs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ public SizeLimitingBatchableSourceSerializer(
5252
_itemSerializer = Ensure.IsNotNull(itemSerializer, nameof(itemSerializer));
5353
_itemElementNameValidator = Ensure.IsNotNull(itemElementNameValidator, nameof(itemElementNameValidator));
5454
_maxBatchCount = Ensure.IsGreaterThanZero(maxBatchCount, nameof(maxBatchCount));
55-
_maxItemSize = Ensure.IsBetween(maxItemSize, 1, int.MaxValue, nameof(maxItemSize));
56-
_maxBatchSize = Ensure.IsBetween(maxBatchSize, maxItemSize, int.MaxValue, nameof(maxBatchSize));
55+
_maxItemSize = Ensure.IsGreaterThanZero(maxItemSize, nameof(maxItemSize));
56+
_maxBatchSize = Ensure.IsGreaterThanZero(maxBatchSize, nameof(maxBatchSize));
5757
}
5858

5959
// public methods
@@ -88,19 +88,23 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati
8888
var item = value.Items[value.Offset + i];
8989
_itemSerializer.Serialize(context, args, item);
9090

91-
var batchSize = binaryWriter?.Position - startPosition;
92-
if (batchSize > _maxBatchSize)
91+
// always process at least one item
92+
if (i > 0)
9393
{
94-
if (i > 0 && value.CanBeSplit)
94+
var batchSize = binaryWriter?.Position - startPosition;
95+
if (batchSize > _maxBatchSize)
9596
{
96-
binaryWriter.BaseStream.Position = itemPosition.Value; // remove the last item
97-
binaryWriter.BaseStream.SetLength(itemPosition.Value);
98-
value.SetProcessedCount(i);
99-
return;
100-
}
101-
else
102-
{
103-
throw new ArgumentException("Batch is too large.");
97+
if (value.CanBeSplit)
98+
{
99+
binaryWriter.BaseStream.Position = itemPosition.Value; // remove the last item
100+
binaryWriter.BaseStream.SetLength(itemPosition.Value);
101+
value.SetProcessedCount(i);
102+
return;
103+
}
104+
else
105+
{
106+
throw new ArgumentException("Batch is too large.");
107+
}
104108
}
105109
}
106110
}

src/MongoDB.Driver.Core/Core/Operations/RetryableDeleteCommandOperation.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ private IBsonSerializer<BatchableSource<DeleteRequest>> CreateBatchSerializer(Co
123123
if (attempt == 1)
124124
{
125125
var maxBatchCount = Math.Min(MaxBatchCount ?? int.MaxValue, connectionDescription.MaxBatchCount);
126-
var maxItemSize = connectionDescription.MaxDocumentSize;
127-
var maxBatchSize = connectionDescription.MaxWireDocumentSize;
126+
var maxItemSize = connectionDescription.MaxWireDocumentSize;
127+
var maxBatchSize = connectionDescription.MaxDocumentSize;
128128
return new SizeLimitingBatchableSourceSerializer<DeleteRequest>(DeleteRequestSerializer.Instance, NoOpElementNameValidator.Instance, maxBatchCount, maxItemSize, maxBatchSize);
129129
}
130130
else

src/MongoDB.Driver.Core/Core/Operations/RetryableInsertCommandOperation.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ private IBsonSerializer<BatchableSource<TDocument>> CreateBatchSerializer(Connec
150150
{
151151
var maxBatchCount = Math.Min(MaxBatchCount ?? int.MaxValue, connectionDescription.MaxBatchCount);
152152
var maxItemSize = connectionDescription.MaxDocumentSize;
153-
var maxBatchSize = connectionDescription.MaxWireDocumentSize;
153+
var maxBatchSize = connectionDescription.MaxDocumentSize;
154154
return new SizeLimitingBatchableSourceSerializer<TDocument>(itemSerializer, elementNameValidator, maxBatchCount, maxItemSize, maxBatchSize);
155155
}
156156
else

src/MongoDB.Driver.Core/Core/Operations/RetryableUpdateCommandOperation.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ private IBsonSerializer<BatchableSource<UpdateRequest>> CreateBatchSerializer(Co
145145
{
146146
var maxBatchCount = Math.Min(MaxBatchCount ?? int.MaxValue, connectionDescription.MaxBatchCount);
147147
var maxItemSize = connectionDescription.MaxWireDocumentSize;
148-
var maxBatchSize = connectionDescription.MaxWireDocumentSize;
148+
var maxBatchSize = connectionDescription.MaxDocumentSize;
149149
return new SizeLimitingBatchableSourceSerializer<UpdateRequest>(UpdateRequestSerializer.Instance, NoOpElementNameValidator.Instance, maxBatchCount, maxItemSize, maxBatchSize);
150150
}
151151
else

tests/MongoDB.Driver.Core.TestHelpers/EventCapturer.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
using System;
1717
using System.Collections.Generic;
18+
using System.Linq;
1819
using MongoDB.Bson;
1920
using MongoDB.Driver.Core.Events;
2021
using MongoDB.Driver.Core.Misc;
@@ -64,6 +65,17 @@ public void Clear()
6465
}
6566
}
6667

68+
public List<object> Events
69+
{
70+
get
71+
{
72+
lock (_lock)
73+
{
74+
return _capturedEvents.ToList();
75+
}
76+
}
77+
}
78+
6779
public object Next()
6880
{
6981
lock (_lock)

0 commit comments

Comments
 (0)