Skip to content

refactor(NODE-4633): executeOperation to use maybeCallback #3421

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
merged 9 commits into from
Sep 28, 2022

Conversation

nbbeeken
Copy link
Contributor

@nbbeeken nbbeeken commented Sep 21, 2022

Description

NODE-4633

What is changing?

  • package-lock.json and package.json
  • src/bulk/common.ts
  • src/collection.ts and src/operations/rename.ts and src/operations/stats.ts and src/operations/delete.ts
    • The promisify type was incompatible with these operation classes because they don't pass their types into the super class generic. Delete was able to be fixed the others lead to numerous TS issues, this all relates to NODE-3286.
  • src/operations/command.ts
    • The override was redundant, could lead to mistakes down the road where the return type generic doesn't make it to the super class.
  • src/operations/execute_operation.ts
    • The whole reason we're here 😸 Leaving executeOperation nearly empty to just call a new TBD named async function was intentional to avoid causing renames across tons of files, but we can do a follow up if we want to do that.
    • Perhaps we don't need to run serverSelection twice? (session support check)
      • No we do, we need to use a difference selector than the user / operation may require.
    • Added a helper to get TS to think topology always exists (it will since we call connect)
    • retryOperation is a helper function now, this isn't a big change it's just not defined inline, so we have to pass it the variables it needs instead of it binding to the current scope.
      • retyability is undergoing a change with CSOT so I think more refactor + feature work will improve this further
  • src/operations/operation.ts
    • Creates the promisified wrapper for .execute()
  • src/sdam/server.ts
    • noResponse was causing endSessions to ALWAYS throw, which we squash, but it prevented executeOperation from retrying. Fixed.
  • src/sdam/topology.ts
    • Makes a promisified wrapper for serverSelection, I would happy to make this a proper async function in a follow up. It's not super complex but will have a significant impact on tests so best to do it on its own.
  • test/integration/crud/bulk.test.ts
    • ⚠️ Forgot to await an insertMany here async/await makes this always fail now. fixed!
  • test/integration/crud/maxTimeMS.test.ts
    • ⚠️ Forgot to await an insertMany here async/await makes this always fail now. fixed!
    • Added printing stack traces to assertions.
  • test/integration/server-selection/operation_count.test.ts
    • the operationCount used to be reached synchronously, we need to add a sleep here to allow the code to reach the increment
  • test/integration/sessions/sessions.spec.prose.test.ts and test/integration/sessions/sessions.test.ts
    • Our minimum session usage for all the parallel operations we run in these tests is now 2. With async await we will never put the first created session back before the next operation attempts to pull one out of the pool. Unlike multithreaded drivers that may have some level of nondeterminism, connection checkIn -> release is deterministically after the next operation reaches the checkOut -> acquire step. As we further refactor to async await I don't expect this to go any higher than 2 but it is possible it could decrease again to 1 if the order of async steps allows us to return the session before the next operation tries to acquire one.

What is the motivation for this change?

async await is easier to reason about, error wise, ordering wise, and forces consistent execution.

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>
  • Changes are covered by tests
  • New TODOs have a related JIRA ticket

@nbbeeken nbbeeken force-pushed the NODE-4633/refactor-executeOperation branch 9 times, most recently from f2c0ad2 to e3d3a1b Compare September 26, 2022 19:04
@nbbeeken nbbeeken marked this pull request as ready for review September 26, 2022 19:52
}

const assertTopology = async (client: MongoClient) => {
const { topology } = client;
Copy link
Contributor

Choose a reason for hiding this comment

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

related - function names should describe what the function does and assertTopology isn't descriptive of what this function does. This function:

  • connects the client
  • asserts the topology is connected
  • returns the topology

At the least, can we use a better name? connectClientAndAssertTopology? That's a mouthful, so I'd probably do the following (just organizational preference)

  1. rename the function connectIfNotConnected or something like this and make it return void so that the function
  2. move the if (topology == null) check to a regular if check outside the function

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I renamed and improved the control flow here, keeping the assertion in here though seems like an acceptable approach because it's really unreachable to have a nullish topology after connect.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should move away from the naming convention maybe<something> because it's not particularly descriptive and after v5, we won't have need for maybeCallback anymore.

maybe even just autoConnect would be better but we could also just move this code back inline - it's only used in once place and isn't terribly complicated so I see no problem with having it inline

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Inlined

}
client.s.options[Symbol.for('@@mdb.skipPingOnConnect')] = true;
await client.connect();
delete client.s.options[Symbol.for('@@mdb.skipPingOnConnect')];
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we need to put this in a finally so that we remove this regardless of whether or not connect fails (that's also the old behavior).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done!

}

const assertTopology = async (client: MongoClient) => {
const { topology } = client;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should move away from the naming convention maybe<something> because it's not particularly descriptive and after v5, we won't have need for maybeCallback anymore.

maybe even just autoConnect would be better but we could also just move this code back inline - it's only used in once place and isn't terribly complicated so I see no problem with having it inline

@nbbeeken nbbeeken force-pushed the NODE-4633/refactor-executeOperation branch from 218eb8f to 0148f5e Compare September 28, 2022 16:54
baileympearson
baileympearson previously approved these changes Sep 28, 2022
@baileympearson baileympearson added the Team Review Needs review from team label Sep 28, 2022
@baileympearson baileympearson merged commit 492456b into main Sep 28, 2022
@baileympearson baileympearson deleted the NODE-4633/refactor-executeOperation branch September 28, 2022 18:25
ZLY201 pushed a commit to ZLY201/node-mongodb-native that referenced this pull request Nov 5, 2022
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
Development

Successfully merging this pull request may close these issues.

3 participants