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

feat(CSOT) - feature branch #4095

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

feat(CSOT) - feature branch #4095

wants to merge 1 commit into from

Conversation

W-A-James
Copy link
Contributor

@W-A-James W-A-James commented Apr 23, 2024

Description

What is changing?

New Error
  • Added MongoOperationTimeoutError class that is thrown when a CSOT timeout is encountered
Changes to Timeout
  • Add Timeout.throwIfExpired() method
  • Add Timeout.remainingTime getter method
Updates to AbstractOperation
  • Add timeout field
    • timeout is set at construction if the timeoutMS option is provided
Implementing CSOT behaviour for server selection
  • Update Topology.selectServer to accept a timeout option which it will use determine whether it has timed out when defined. Otherwise, constructs a Timeout using the serverSelectionMS option as before
  • Update Topology.selectServer to throw a MongoOperationTimeoutError on timeout when options.timeout is provided and retain previous error behaviour otherwise.
  • Update Topology._connect to pass down timeout to Server.command call used to execute ping on first connection
Implementing CSOT behaviour for connection checkout
  • Update Server.command to accept timeout option.
  • Update ConnectionPool.checkOut to accept timeout option
    • only uses the passed in timeout if the configured serverSelectionTimeoutMS is greater than the duration on the timeout, otherwise, computes the time elapsed since server selection completed and creates timeout for the serverSelectionTimeoutMS deadline
Test changes
  • Implement Server Selection prose tests from CSOT spec. Left out last two since they require implementation of the connection creation cancellation behaviour that was decided against in DRIVERS-2347
  • Implement unit tests from CSOT spec related to server selection and connection checkout. Skipped tests with appropriate messages
Misc changes
  • Update resolveOptions to handle timeoutMS option propagation
    • Add csotMin helper method that implements the CSOT min algorithm described here
Is there new documentation needed for these changes?

What is the motivation for this change?

Release Highlight

Fill in title or leave empty for no highlight

Double check the following

  • Ran npm run check:lint script
  • Self-review completed using the steps outlined here
  • PR title follows the correct format: type(NODE-xxxx)[!]: description
    • Example: feat(NODE-1234)!: rewriting everything in coffeescript
  • Changes are covered by tests
  • New TODOs have a related JIRA ticket

@W-A-James W-A-James force-pushed the NODE-6090 branch 2 times, most recently from 5688ba8 to b878c6c Compare April 26, 2024 23:48
src/cmap/connect.ts Outdated Show resolved Hide resolved
src/cmap/connect.ts Outdated Show resolved Hide resolved
src/cmap/connection.ts Outdated Show resolved Hide resolved
src/cmap/connection_pool.ts Outdated Show resolved Hide resolved
src/cmap/connection_pool.ts Outdated Show resolved Hide resolved
src/error.ts Show resolved Hide resolved
src/operations/operation.ts Outdated Show resolved Hide resolved
@W-A-James W-A-James changed the title Node 6090 refactor(NODE-6090): Implement CSOT logic for server selection and connection checkout May 3, 2024
@W-A-James W-A-James changed the base branch from main to CSOT-feature May 3, 2024 21:27
Comment on lines +81 to +82
readPreference: options?.readPreference,
timeoutMS: options?.timeoutMS ?? this.s.db.timeoutMS
Copy link
Contributor Author

Choose a reason for hiding this comment

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

NOTE FOR REVIEWERS: Needed to do this to ensure that unit tests using ping work

@W-A-James
Copy link
Contributor Author

Evergreen link

@W-A-James W-A-James marked this pull request as ready for review May 3, 2024 22:19
Copy link
Contributor

@baileympearson baileympearson left a comment

Choose a reason for hiding this comment

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

left some small comments. I'm out this week, so don't consider them blocking!

Comment on lines 330 to 333
return await Promise.race([
finalOptions.operationTimeout,
conn.command(ns, cmd, finalOptions)
]);
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't recall any CSOT requirement that states we should time out the entirety of command execution at the connection layer. Instead, each step of connection-layer command execution has its own rules (your PR description mentions that this PR does not implement this logic.

Is this only added to facilitate testing? Or is there a CSOT requirement I'm missing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch here. Meant to remove this change, but missed it.

src/sdam/server.ts Show resolved Hide resolved
src/sdam/server.ts Outdated Show resolved Hide resolved
src/operations/operation.ts Show resolved Hide resolved
src/sdam/topology.ts Show resolved Hide resolved
src/operations/execute_operation.ts Outdated Show resolved Hide resolved
@aditi-khare-mongoDB aditi-khare-mongoDB added Primary Review In Review with primary reviewer, not yet ready for team's eyes and removed Primary Review In Review with primary reviewer, not yet ready for team's eyes labels May 6, 2024
@nbbeeken nbbeeken self-requested a review May 6, 2024 16:07
@aditi-khare-mongoDB aditi-khare-mongoDB self-assigned this May 6, 2024
@aditi-khare-mongoDB aditi-khare-mongoDB added the Primary Review In Review with primary reviewer, not yet ready for team's eyes label May 6, 2024
@aditi-khare-mongoDB
Copy link
Contributor

Bookkeeping:
Waiting for Warren to respond to Bailey's comments and will proceed with review then.

@W-A-James W-A-James changed the base branch from CSOT-feature to main May 7, 2024 17:45
src/sdam/topology.ts Outdated Show resolved Hide resolved
src/sdam/server.ts Outdated Show resolved Hide resolved
src/sdam/topology.ts Outdated Show resolved Hide resolved
@W-A-James
Copy link
Contributor Author

@aditi-khare-mongoDB @nbbeeken should we conditionally clear the timeout on success/a non-timeout failure based on whether or not we created the timeout inside the function that we race the timeout with?
I ask because we don't always own Timeout instance we're using in Topology.selectServer or in ConnectionPool.checkOut.

src/cmap/connection_pool.ts Outdated Show resolved Hide resolved
@aditi-khare-mongoDB aditi-khare-mongoDB added Team Review Needs review from team and removed Primary Review In Review with primary reviewer, not yet ready for team's eyes labels May 7, 2024
Copy link
Contributor

@nbbeeken nbbeeken left a comment

Choose a reason for hiding this comment

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

looks pretty good

src/operations/operation.ts Show resolved Hide resolved
src/cmap/connection.ts Show resolved Hide resolved
src/cmap/connection_pool.ts Outdated Show resolved Hide resolved
src/cmap/connection_pool.ts Outdated Show resolved Hide resolved
Comment on lines 313 to 317
if (options.operationTimeout) {
conn = await this.pool.checkOut({ timeout: options.operationTimeout });
} else {
conn = await this.pool.checkOut();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if (options.operationTimeout) {
conn = await this.pool.checkOut({ timeout: options.operationTimeout });
} else {
conn = await this.pool.checkOut();
}
conn = await this.pool.checkOut({ timeout: options.operationTimeout });

TS supports just calling this because the timeout is optional

Copy link
Contributor

Choose a reason for hiding this comment

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

I feel Warren's current code is easier to read (and easier for someone editing the code later to not accidentally make the code not CSOT spec-compliant) , but if we do end up going with this suggestion can we leave a clarifying comment?

Copy link
Contributor

Choose a reason for hiding this comment

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

I am surprised because breaking this up into two calls to checkOut based on a condition that does matter is more to read without more meaningful context given. Whether or not timeout exists, there is no change to how checkOut is, practically, invoked because the typescript reports that field as optional.

I would actually take this further:

conn = await this.pool.checkOut(options);

Why do we need to make a new object here? passing through options should be fine right? Less branching paths the less there is to debug

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you elaborate on what may accidentally break the spec without a test warning us?

src/cmap/connection_pool.ts Outdated Show resolved Hide resolved
src/cmap/connection_pool.ts Outdated Show resolved Hide resolved
@W-A-James W-A-James requested a review from nbbeeken May 10, 2024 16:06
// Determine if we're using the timeout passed in or a new timeout
if (options.timeout.duration > 0 || serverSelectionTimeoutMS > 0) {
if (
csotMin(options.timeout.duration, serverSelectionTimeoutMS) === serverSelectionTimeoutMS
Copy link
Contributor

Choose a reason for hiding this comment

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

This is still and equals check, sorry I think we discussed it but didn't leave a comment, if duration is the same then we'll create a new timeout when we can use the existing one.

src/sdam/topology.ts Outdated Show resolved Hide resolved
@W-A-James W-A-James requested a review from nbbeeken May 10, 2024 19:36
nbbeeken
nbbeeken previously approved these changes May 10, 2024
src/sdam/topology.ts Show resolved Hide resolved
src/operations/operation.ts Show resolved Hide resolved
src/sdam/topology.ts Show resolved Hide resolved
@baileympearson baileympearson changed the title refactor(NODE-6090): Implement CSOT logic for server selection and connection checkout feat(CSOT) - feature branch May 29, 2024
@W-A-James W-A-James force-pushed the NODE-6090 branch 2 times, most recently from 4993bbe to e3b7a63 Compare June 5, 2024 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Team Review Needs review from team
Projects
None yet
4 participants