Skip to content
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

GODRIVER-3217 Use the manually-specified maxTimeMS on Find and Aggregate if it would be ommitted by CSOT #1644

Merged
merged 2 commits into from
Jun 12, 2024

Conversation

matthewdale
Copy link
Collaborator

GODRIVER-3217

Summary

If maxTimeMS is specified on a Find or Aggregate operation, always use it to set maxTimeMS on the command, even if CSOT is enabled.

Background & Motivation

#1589 enabled sending an automatically calculated maxTimeMS with (almost) every command when CSOT is enabled. However, it doesn't send maxTimeMS on Find and Aggregate commands because it also sets a server-side lifetime on the cursor created by the command, which is surprising to many users. An unintended side effect of that change is that maxTimeMS is ignored for Find and Aggregate commands, meaning that there is no currently no way to set maxTimeMS on a Find or Aggregate when CSOT is enabled. We want to allow users to set maxTimeMS if they need to.

Note that this behavior will become irrelevant once GODRIVER-2944 is complete.

@mongodb-drivers-pr-bot mongodb-drivers-pr-bot bot added the priority-3-low Low Priority PR for Review label May 22, 2024
Copy link

API Change Report

No changes found!


// TODO(GODRIVER-2944): Remove this test once the "timeoutMode" option is
// supported.
mt.RunOpts("Find always sends manually-specified maxTimeMS", csotOpts, func(mt *mtest.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This test is being run with a client-level timeout of 10 seconds, set by previous subtests. The csotOpts should be reset before executing to test that the deprecated operation-level maxTimeMS value is being propagated to command message when omitting CSOT.

Suggested change
mt.RunOpts("Find always sends manually-specified maxTimeMS", csotOpts, func(mt *mtest.T) {
csotOpts = mtest.NewOptions().ClientOptions(options.Client())
mt.RunOpts("Find always sends manually-specified maxTimeMS", csotOpts, func(mt *mtest.T) {

Suggest adding the following function to test that a 5s timeout is being used:

assertMaxTimeMS := func(mt *mtest.T, command bson.Raw, expected int64) {
	mt.Helper()

	maxTimeVal := command.Lookup("maxTimeMS")

	require.Greater(mt,
		len(maxTimeVal.Value),
		0,
		"expected maxTimeMS BSON value to be non-empty")
	require.Equal(mt,
		maxTimeVal.Type,
		bson.TypeInt64,
		"expected maxTimeMS BSON value to be type Int64")
	assert.Greater(mt,
		maxTimeVal.Int64(),
		int64(0),
		"expected maxTimeMS value to be greater than 0")
	assert.Equal(mt, expected, maxTimeVal.Int64())
}

Also suggest creating an additional test ensuring behavior defined in the Validation and Overrides section of the CSOT specifications:

When executing an operation, drivers MUST ignore any deprecated timeout options if timeoutMS is set on the operation or is inherited from the collection/database/client levels.

csotOpts = mtest.NewOptions().ClientOptions(options.Client().SetTimeout(15 * time.Second))
mt.RunOpts("Find sends client-level timeout over deprecated maxTimeMS", csotOpts, func(mt *mtest.T) {
	ctx := context.Background()

	// Manually set a maxTimeMS on the Find and assert that it's sent with
	// the command, even when CSOT is enabled.
	cursor, err := mt.Coll.Find(
		ctx,
		bson.D{},
		options.Find().SetMaxTime(5*time.Second))
	require.NoError(mt, err, "Find error")
	err = cursor.Close(context.Background())
	require.NoError(mt, err, "Cursor.Close error")

	evt := getStartedEvent(mt, "find")
	fmt.Println(evt)
	//assertMaxTimeMSIsSet(mt, evt.Command)
	assertMaxTimeMS(mt, evt.Command, 15000)
})

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the test matrix should look something like this:

  1. no client-level, operation-level, deprecated operation-level -> use DOL
  2. ~CL, ~OL, DOL -> DOL
  3. CL, OL, DOL -> DOL
  4. CL, ~OL, DOL -> CL

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The current test case is basically

CL, OL, DOL -> DOL

so setting timeoutMS is intentional. However, the test doesn't cover the rest of the cases, which could be confusing (especially because the test description is actually incorrect, since a manually-set maxTimeMS is ignored when a client-level timeout is set but no operation-level timeout is set).

I'll update the test to cover the additional cases.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I added test cases for the permutations you described.


// TODO(GODRIVER-2944): Remove this test once the "timeoutMode" option is
// supported.
mt.RunOpts("Aggregate always sends manually-specified maxTimeMS", csotOpts, func(mt *mtest.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same considerations for "Find always sends manually-specified maxTimeMS" apply to the aggregate counterpart.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I added test cases for the permutations described in the other comment.

@matthewdale matthewdale changed the title GODRIVER-3217 Always use the manually-specified maxTimeMS on Find and Aggregate GODRIVER-3217 Use the manually-specified maxTimeMS on Find and Aggregate if it would be ommitted by CSOT Jun 11, 2024
@matthewdale matthewdale merged commit 4f7331d into mongodb:v1 Jun 12, 2024
22 of 26 checks passed
matthewdale added a commit that referenced this pull request Jun 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority-3-low Low Priority PR for Review
Projects
None yet
2 participants