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(NODE-2014)!: return executor result from withSession and withTransaction #3783

Merged
merged 7 commits into from
Jul 27, 2023

Conversation

nbbeeken
Copy link
Contributor

@nbbeeken nbbeeken commented Jul 24, 2023

Description

What is changing?

  • withSession & withTransaction return the value returned by the provided functions
Is there new documentation needed for these changes?

Yes, API docs have been updated. Look for docs changes needed on the ticket

What is the motivation for this change?

See highlight.

Release Highlight

withSession and withTransaction return the value returned by the provided function

The await client.withSession(async session => {}) now returns the value that the provided function returns. Previously, this function returned void this is a feature to align with the following breaking change.

The await session.withTransaction(async () => {}) method now returns the value that the provided function returns. Previously, this function returned the server command response which is subject to change depending on the server version or type the driver is connected to. The return value got in the way of writing robust, reliable, consistent code no matter the backing database supporting the application.

⚠️ Attention! withTransaction breaking change

Important

When upgrading to this version of the driver audit the usages of withTransaction for if statements or other conditional checks on the return value of withTransaction. Previously, the return value was the command response if the transaction was committed, and undefined if it had been manually aborted. It would only throw if an operation or the author of the function threw an error. Since thus far there has not been the ability to get the result of the function passed to withTransaction we suspect most existing usages to return void, making withTransaction a void returning function in this major release. Take care to ensure that the return values of your function match the expectation of the code that follows the completion of withTransaction.

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
  • Release Notes

@nbbeeken nbbeeken marked this pull request as ready for review July 24, 2023 22:02
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.

some questions

src/mongo_client.ts Outdated Show resolved Hide resolved
test/types/sessions.test-d.ts Show resolved Hide resolved
src/sessions.ts Outdated
}

return attemptTransactionCommit(session, startTime, fn, options);
return attemptTransactionCommit(session, startTime, fn, options).then(() => result);
Copy link
Contributor

Choose a reason for hiding this comment

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

What happens if we need to retry the transaction? I think we'd get incorrect behavior, because the first call to attemptTransaction would always return the result of the first call to fn - but I'd assume that we want to return the result associated with the successful attemptTransaction.

Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps this is okay and expected behavior? We document that Client.withSession may call its callback more than once - we should here too at the very least. But I think since we may call the callback twice, it's an acceptable limitation that the callback should be idempotent.

Copy link
Contributor

Choose a reason for hiding this comment

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

edit: it is noted for this method

Copy link
Contributor Author

Choose a reason for hiding this comment

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

pending slack convo

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to return the last result and added a test

@@ -591,18 +589,18 @@ function attemptTransaction<TSchema>(

if (!isPromiseLike(promise)) {
session.abortTransaction().catch(() => null);
throw new MongoInvalidArgumentError(
'Function provided to `withTransaction` must return a Promise'
return Promise.reject(
Copy link
Contributor

Choose a reason for hiding this comment

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

Why'd you revert the throw?

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 guess it ends up being equivalent only because the caller is now an async function, but throwing here is incorrect since it changes the expectation that this function is always promise returning. I don't feel strongly about keeping this, esp with the ticket to refactor this properly coming up.

Copy link
Contributor

Choose a reason for hiding this comment

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

I was just curious, this change is fine. It'll be moot once Malik gets to this code anyways

@nbbeeken nbbeeken requested a review from baileympearson July 26, 2023 16:48
})
.finally(async () => await session.endSession());

expect(withTransactionResult).to.equal(counter);
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
expect(withTransactionResult).to.equal(counter);
expect(withTransactionResult).to.equal(3);

either we do this, or we somehow assert that the transaction was retried. this test would pass as-is if the failpoint were never triggered

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed this and the manual abort test

@@ -591,18 +589,18 @@ function attemptTransaction<TSchema>(

if (!isPromiseLike(promise)) {
session.abortTransaction().catch(() => null);
throw new MongoInvalidArgumentError(
'Function provided to `withTransaction` must return a Promise'
return Promise.reject(
Copy link
Contributor

Choose a reason for hiding this comment

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

I was just curious, this change is fine. It'll be moot once Malik gets to this code anyways

@nbbeeken nbbeeken requested a review from baileympearson July 26, 2023 18:18
@baileympearson baileympearson added the Primary Review In Review with primary reviewer, not yet ready for team's eyes label Jul 26, 2023
@baileympearson baileympearson self-assigned this Jul 26, 2023
@baileympearson baileympearson added Team Review Needs review from team and removed Primary Review In Review with primary reviewer, not yet ready for team's eyes labels Jul 26, 2023
@W-A-James W-A-James self-requested a review July 26, 2023 19:15
@baileympearson baileympearson merged commit 65aa288 into main Jul 27, 2023
@baileympearson baileympearson deleted the NODE-2014-withX branch July 27, 2023 14:25
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