Skip to content

Refactor MixedBulkWriteOperation a bit and change CommandMessage.isResponseExpected such that it accounts for ordered/unordered bulk writes #1481

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

Merged

Conversation

stIncMale
Copy link
Member

No description provided.

@stIncMale stIncMale requested a review from jyemin August 15, 2024 02:11
@stIncMale stIncMale self-assigned this Aug 15, 2024
Comment on lines -105 to -108
if (sessionContext.hasSession() && !sessionContext.isImplicitSession() && !sessionContext.hasActiveTransaction()
&& !writeConcern.isAcknowledged()) {
throw new MongoClientException("Unacknowledged writes are not supported when using an explicit session");
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This validation was moved to MixedBulkWriteOperation.validateAndGetEffectiveWriteConcern.

Comment on lines -172 to -174
if (!writeConcern.isServerDefault() && !sessionContext.hasActiveTransaction()) {
command.put("writeConcern", writeConcern.asDocument());
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic needs to be reused in the implementation of the new bulkWrite command, so I extracted it into MixedBulkWriteOperation.commandWriteConcern.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will it eventually move to some common "helper" class?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had no such plans, as I don't see any value in creating a somewhat useless class just to hold this method, such that both MixedBulkWriteOperation and ClientBulkWriteOperation could call commandWriteConcern on that class. Calling commandWriteConcern on MixedBulkWriteOperation seems to be not worse in any way, especially given that when it is statically imported, one can't even notice immediately see where the method comes from.

Comment on lines +456 to 458
private boolean shouldExpectResponse(final BulkWriteBatch batch, final WriteConcern effectiveWriteConcern) {
return effectiveWriteConcern.isAcknowledged() || (ordered && batch.hasAnotherBatch());
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldExpectResponse replaces the shouldAcknowledge method. The new method has simpler body and named in a way that avoids erroneous allusions to an unacknowledged (w: 0) write concern.

@@ -253,7 +253,7 @@ private boolean requireOpMsgResponse() {
if (responseExpected) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can simplify this class bit further by adding the following assertion in the constructor:

assertFalse(getOpCode() == OpCode.OP_QUERY && !responseExpected);

this assertion should never fire because OP_QUERY effectively is only used for the initial hello command on a new connection, which should always be expecting a response.

Then we can remove the !useOpMsg() condition in isResponseExpected, and inline this method.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 020698b.

Comment on lines -172 to -174
if (!writeConcern.isServerDefault() && !sessionContext.hasActiveTransaction()) {
command.put("writeConcern", writeConcern.asDocument());
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will it eventually move to some common "helper" class?

@stIncMale stIncMale changed the title Refactor MixedBulkWriteOperation a bit and change CommandMessage.requireOpMsgResponse such that it accounts for ordered/unordered bulk writes Refactor MixedBulkWriteOperation a bit and change CommandMessage.isResponseExpected such that it accounts for ordered/unordered bulk writes Aug 15, 2024
@stIncMale stIncMale requested a review from jyemin August 15, 2024 17:54
@@ -350,9 +351,11 @@ class MongoClientSessionSpecification extends FunctionalSpecification {

void waitForInsertAcknowledgement(MongoCollection<Document> collection, ObjectId id) {
Document document = collection.find(Filters.eq(id)).first()
Timeout timeout = Timeout.expiresIn(5, TimeUnit.SECONDS, Timeout.ZeroSemantics.ZERO_DURATION_MEANS_INFINITE)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change relevant to the rest of the PR?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 352 to 360
void waitForInsertAcknowledgement(MongoCollection<Document> collection, ObjectId id) {
Document document = collection.find(Filters.eq(id)).first()
Timeout timeout = Timeout.expiresIn(5, TimeUnit.SECONDS, Timeout.ZeroSemantics.ZERO_DURATION_MEANS_INFINITE);
while (document == null) {
Thread.sleep(1)
document = collection.find(Filters.eq(id)).first()
timeout.onExpired {throw new RuntimeException("Timed out waiting for insert acknowledgement")}
}
}
Copy link
Member Author

@stIncMale stIncMale Aug 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When playing with the assertion added to SplittablePayload.hasAnotherSplit, I noticed that this method makes the tests hang if assertion error happens. So I introduced a timeout. When the assertion error is thrown and timeout expires, the assertion error is observable in the stack trace of the exception thrown by the test (I manually checked that).

@@ -253,7 +253,7 @@ private boolean requireOpMsgResponse() {
if (responseExpected) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 020698b.

while (document == null) {
Thread.sleep(1)
document = collection.find(Filters.eq(id)).first()
timeout.onExpired { assert !"Timed out waiting for insert acknowledgement".trim() }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The checker is not happy when I throw RuntimeException, so I decided to use Spock's assert. However, it does not take a message, so I used a negation of the error message to emulate the failure message. But then the checker wasn't happy because it could see that the assertion outcome is predetermined, which is why I had to use trim (toString did not fool the checker).

@stIncMale stIncMale merged commit d8f91fb into mongodb:master Aug 15, 2024
59 checks passed
@stIncMale stIncMale deleted the JAVA-4586_minor-bulkWrite-improvements branch August 15, 2024 22:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants