Skip to content

Conversation

qingyang-hu
Copy link
Collaborator

GODRIVER-3582

Summary

  • Add bypassEmptyTsReplacement for client bulkWrite.
  • Add a generic callback function to allow undocumented parameters in client bulkWrite commands

Background & Motivation

Copy link
Contributor

mongodb-drivers-pr-bot bot commented Aug 18, 2025

🧪 Performance Results

Commit SHA: 4dd4232

The following benchmark tests for version 68a75c2ad3686000077f5b6b had statistically significant changes (i.e., |z-score| > 1.96):

Benchmark Measurement % Change Patch Value Stable Region H-Score Z-Score
BenchmarkSingleRunCommand ops_per_second_min -73.0803 432.5097 Avg: 1606.6647
Med: 1632.1494
Stdev: 186.6319
0.9206 -6.2913
BenchmarkBSONDeepDocumentDecoding ops_per_second_min -13.9768 1702.3769 Avg: 1978.9743
Med: 1986.4050
Stdev: 122.4366
0.7556 -2.2591
BenchmarkSingleFindOneByID total_mem_allocs -10.9457 1479405.0000 Avg: 1661239.6010
Med: 1669130.0000
Stdev: 68961.1725
0.7863 -2.6368
BenchmarkSingleFindOneByID total_bytes_allocated -10.1943 92089912.0000 Avg: 102543516.0207
Med: 103038568.0000
Stdev: 4237743.0995
0.7716 -2.4668

For a comprehensive view of all microbenchmark results for this PR's commit, please check out the Evergreen perf task for this patch.

Copy link
Contributor

API Change Report

No changes found!

@qingyang-hu qingyang-hu marked this pull request as ready for review August 19, 2025 22:10
@Copilot Copilot AI review requested due to automatic review settings August 19, 2025 22:10
@qingyang-hu qingyang-hu requested a review from a team as a code owner August 19, 2025 22:10
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for two new internal options to the client bulkWrite functionality: a boolean flag for bypassing empty timestamp replacement and a generic callback function for adding undocumented parameters to commands.

  • Adds bypassEmptyTsReplacement boolean option for client bulkWrite operations
  • Implements a commandCallback function option to allow dynamic command modifications
  • Updates command building logic to incorporate these new options

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
x/mongo/driver/xoptions/options.go Adds option parsing for new bypassEmptyTsReplacement and commandCallback parameters
mongo/client_bulk_write.go Updates clientBulkWrite struct and command building logic to support new options
mongo/client.go Extracts and sets new options from internal options during client bulkWrite execution
internal/integration/client_test.go Adds integration test for commandCallback functionality

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@@ -101,6 +102,24 @@ func SetInternalClientBulkWriteOptions(a *options.ClientBulkWriteOptionsBuilder,
opts.Internal = optionsutil.WithValue(opts.Internal, key, b)
return nil
})
case "bypassEmptyTsReplacement":
Copy link
Member

Choose a reason for hiding this comment

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

Should we skip adding bypassEmptyTsReplacement, instead deferring to the user to set it using the command callback?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Despite being internal, I recommend retaining helper functions like bypassEmptyTsReplacement since the command callback shouldn't be used frequently.

if bw.bypassEmptyTsReplacement != nil {
dst = bsoncore.AppendBooleanElement(dst, "bypassEmptyTsReplacement", *bw.bypassEmptyTsReplacement)
}
if bw.commandCallback != nil {
Copy link
Member

Choose a reason for hiding this comment

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

IIUC this callback is designed to be a final mutator and so is kind of a dangerous addition to the code since it has to always come last in the function returned by newCommand. At the very least we should note that in a comment.

For long-term maintenance and to avoid bugs, it might be best to enforce this behavior. Perhaps we could use a builder pattern:

type clientBulkWrite struct {
	builder commandBuilder
}
type commandBuilder struct {
	base func([]byte, description.SelectedServer) ([]byte, error)
	callback func([]byte, description.ServerSelector) ([]byte, error)
}

func (b commandBuilder) build(dst []byte, desc description.SelectedServer) ([]byte, error) {
	out, err := b.base(dst, desc)
	if err != nil {
		return nil, err
	}

	// The callback is a final mutator.
	if b.callback != nil {
		out, err := b.callback(out, desc)
		if err != nil {
			return nil, err 
		}
	}

	return out, nil
}

Then in newCommand():

bw.builder.base = func(dst []byte, desc description.SelectedServer) ([]byte, error) {
	// ...
}

return bw.builder.build

@prestonvasquez prestonvasquez added the review-priority-normal Medium Priority PR for Review: within 1 business day label Aug 20, 2025
Copy link
Collaborator

@matthewdale matthewdale left a comment

Choose a reason for hiding this comment

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

The implementation looks good. 👍 We should wait to hear back if it accomplishes the mongosync use case before merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement review-priority-normal Medium Priority PR for Review: within 1 business day
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants