-
Notifications
You must be signed in to change notification settings - Fork 1.3k
CSHARP-1378: Make BulkWrite enumerate requests argument only once #1298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -218,27 +218,30 @@ public override MongoCollectionSettings Settings | |
public override BulkWriteResult<TDocument> BulkWrite(IClientSessionHandle session, IEnumerable<WriteModel<TDocument>> requests, BulkWriteOptions options, CancellationToken cancellationToken = default(CancellationToken)) | ||
{ | ||
Ensure.IsNotNull(session, nameof(session)); | ||
Ensure.IsNotNull(requests, nameof(requests)); | ||
if (!requests.Any()) | ||
Ensure.IsNotNull((object)requests, nameof(requests)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This unnecessary cast to object needed to make code analysis happy, otherwise it says we might be doing multiple enumeration of the |
||
|
||
var requestsArray = requests.ToArray(); | ||
if (requestsArray.Length == 0) | ||
{ | ||
throw new ArgumentException("Must contain at least 1 request.", "requests"); | ||
throw new ArgumentException("Must contain at least 1 request.", nameof(requests)); | ||
} | ||
foreach (var request in requests) | ||
|
||
foreach (var request in requestsArray) | ||
{ | ||
request.ThrowIfNotValid(); | ||
} | ||
|
||
options = options ?? new BulkWriteOptions(); | ||
|
||
var operation = CreateBulkWriteOperation(session, requests, options); | ||
var operation = CreateBulkWriteOperation(session, requestsArray, options); | ||
try | ||
{ | ||
var result = ExecuteWriteOperation(session, operation, cancellationToken); | ||
return BulkWriteResult<TDocument>.FromCore(result, requests); | ||
return BulkWriteResult<TDocument>.FromCore(result, requestsArray); | ||
} | ||
catch (MongoBulkWriteOperationException ex) | ||
{ | ||
throw MongoBulkWriteException<TDocument>.FromCore(ex, requests.ToList()); | ||
throw MongoBulkWriteException<TDocument>.FromCore(ex, requestsArray); | ||
} | ||
} | ||
|
||
|
@@ -250,27 +253,30 @@ public override MongoCollectionSettings Settings | |
public override async Task<BulkWriteResult<TDocument>> BulkWriteAsync(IClientSessionHandle session, IEnumerable<WriteModel<TDocument>> requests, BulkWriteOptions options, CancellationToken cancellationToken = default(CancellationToken)) | ||
{ | ||
Ensure.IsNotNull(session, nameof(session)); | ||
Ensure.IsNotNull(requests, nameof(requests)); | ||
if (!requests.Any()) | ||
Ensure.IsNotNull((object)requests, nameof(requests)); | ||
|
||
var requestsArray = requests.ToArray(); | ||
if (requestsArray.Length == 0) | ||
{ | ||
throw new ArgumentException("Must contain at least 1 request.", "requests"); | ||
throw new ArgumentException("Must contain at least 1 request.", nameof(requests)); | ||
} | ||
foreach (var request in requests) | ||
|
||
foreach (var request in requestsArray) | ||
{ | ||
request.ThrowIfNotValid(); | ||
} | ||
|
||
options = options ?? new BulkWriteOptions(); | ||
|
||
var operation = CreateBulkWriteOperation(session, requests, options); | ||
var operation = CreateBulkWriteOperation(session, requestsArray, options); | ||
try | ||
{ | ||
var result = await ExecuteWriteOperationAsync(session, operation, cancellationToken).ConfigureAwait(false); | ||
return BulkWriteResult<TDocument>.FromCore(result, requests); | ||
return BulkWriteResult<TDocument>.FromCore(result, requestsArray); | ||
} | ||
catch (MongoBulkWriteOperationException ex) | ||
{ | ||
throw MongoBulkWriteException<TDocument>.FromCore(ex, requests.ToList()); | ||
throw MongoBulkWriteException<TDocument>.FromCore(ex, requestsArray); | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ | |
using System.Linq.Expressions; | ||
using System.Net; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using FluentAssertions; | ||
using MongoDB.Bson; | ||
using MongoDB.Bson.Serialization; | ||
|
@@ -31,6 +32,7 @@ | |
using MongoDB.Driver.Core.Operations; | ||
using MongoDB.Driver.Core.Servers; | ||
using MongoDB.Driver.Core.TestHelpers.XunitExtensions; | ||
using MongoDB.Driver.TestHelpers; | ||
using MongoDB.Driver.Tests; | ||
using Moq; | ||
using Xunit; | ||
|
@@ -442,6 +444,37 @@ public void AggregateToCollection_should_throw_when_last_stage_is_not_an_output_ | |
exception.Should().BeOfType<InvalidOperationException>(); | ||
} | ||
|
||
[Theory] | ||
[ParameterAttributeData] | ||
public async Task BulkWrite_should_enumerate_requests_once([Values(false, true)] bool async) | ||
{ | ||
var subject = CreateSubject<BsonDocument>(); | ||
var document = new BsonDocument("_id", 1).Add("a", 1); | ||
var requests = new WriteModel<BsonDocument>[] | ||
{ | ||
new InsertOneModel<BsonDocument>(document) | ||
}; | ||
var processedRequest = new InsertRequest(document) { CorrelationId = 0 }; | ||
var operationResult = new BulkWriteOperationResult.Acknowledged( | ||
requestCount: 1, | ||
matchedCount: 0, | ||
deletedCount: 0, | ||
insertedCount: 1, | ||
modifiedCount: 0, | ||
processedRequests: new[] { processedRequest }, | ||
upserts: new List<BulkWriteOperationUpsert>()); | ||
_operationExecutor.EnqueueResult<BulkWriteOperationResult>(operationResult); | ||
var wrappedRequests = new Mock<IEnumerable<WriteModel<BsonDocument>>>(); | ||
wrappedRequests.Setup(e => e.GetEnumerator()).Returns(((IEnumerable<WriteModel<BsonDocument>>)requests).GetEnumerator()); | ||
|
||
var result = async ? await subject.BulkWriteAsync(wrappedRequests.Object) : subject.BulkWrite(wrappedRequests.Object); | ||
|
||
wrappedRequests.Verify(e => e.GetEnumerator(), Times.Once); | ||
result.Should().NotBeNull(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Basically we testing here is there were no exception, as |
||
result.RequestCount.Should().Be(1); | ||
result.ProcessedRequests.ShouldBeEquivalentTo(requests); | ||
} | ||
|
||
[Theory] | ||
[ParameterAttributeData] | ||
public void BulkWrite_should_execute_a_BulkMixedWriteOperation( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not related to the PR itself, but it fixes some warnings we got on build