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

fix(medusa): Idempotency workStage used within transaction #2358

Merged
merged 7 commits into from
Oct 19, 2022

Conversation

adrien2p
Copy link
Member

@adrien2p adrien2p commented Oct 5, 2022

What
The actual idempotency service workStage method was in a try catch block, when a transaction to wrap the work as been added, the try catch have created some side effects due to the fact that the transaction does not fail and end up in a specific state where the some data are rollback and some other data are committed.

How
Remove the try catch from the workStage and instead the catch must been placed at the higher level of transaction since we want to know if the transaction failed.

Tests
Add new integration test on the create-claims order as this is the one which have triggered this. The tests purposefully create a claim item with item without return reason which lead to an error. We then validate that there is no more claim order in the database once the stage has failed.

Notes
The other way of fixing it would be that the work stage create a child transaction serializable from either manager_ | transactionManager_.

FIXES CORE-680

@changeset-bot
Copy link

changeset-bot bot commented Oct 5, 2022

🦋 Changeset detected

Latest commit: c7ea7b1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@medusajs/medusa Minor
medusa-react Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@adrien2p adrien2p closed this Oct 5, 2022
@adrien2p adrien2p reopened this Oct 5, 2022
@adrien2p adrien2p marked this pull request as ready for review October 5, 2022 09:33
@adrien2p adrien2p requested a review from a team as a code owner October 5, 2022 09:33
@adrien2p adrien2p force-pushed the fix/claim-service-transaction branch from 9bb5cb1 to 73afcc9 Compare October 5, 2022 09:48
Copy link
Contributor

@pKorsholm pKorsholm left a comment

Choose a reason for hiding this comment

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

If this is the solution we choose I think the code looks good. We just need to remove the error parameter from the return type.

What is the reasoning to choose this approach over, as you write, creating a transaction in the workStage method in order to get a proper rollback?

To me it seems that it would be the safer choice to use a transaction inside the workStage and it seems to logically make sense as well, not saying this doesn't, but it's not outrageous to create a transaction in the workStage in order to make sure that it's properly rolled back if something failed. We are wrapping all the workStage invocations in transactions individually anyway, this would clean up the invocation a bit. Furthermore throwing and not catching breaks the api of the service. In turn if anybody has implemented custom services using this they are required to update it.
Not saying that we shouldn't break the API as certain points, just that we need to be wary.

@@ -172,27 +172,23 @@ class IdempotencyKeyService extends TransactionBaseService {
| never
>
): Promise<{ key?: IdempotencyKey; error?: unknown }> {
Copy link
Contributor

Choose a reason for hiding this comment

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

remove error return param

@olivermrbl olivermrbl changed the title Fix(medusa): Idempotency workStage used within transaction fix(medusa): Idempotency workStage used within transaction Oct 6, 2022
@adrien2p
Copy link
Member Author

adrien2p commented Oct 6, 2022

If this is the solution we choose I think the code looks good. We just need to remove the error parameter from the return type.

What is the reasoning to choose this approach over, as you write, creating a transaction in the workStage method in order to get a proper rollback?

To me it seems that it would be the safer choice to use a transaction inside the workStage and it seems to logically make sense as well, not saying this doesn't, but it's not outrageous to create a transaction in the workStage in order to make sure that it's properly rolled back if something failed. We are wrapping all the workStage invocations in transactions individually anyway, this would clean up the invocation a bit. Furthermore throwing and not catching breaks the api of the service. In turn if anybody has implemented custom services using this they are required to update it. Not saying that we shouldn't break the API as certain points, just that we need to be wary.

I totally agree with the fact that it breaks a bit the way it works actually. But i think it is a trade off until we settle on the transaction refactoring to introduce a new pattern. At the moment, if a user is using the idempotency service without calling the withTransaction it will be broken on concurrent requests. If a user call the idempotency service in a transaction wrapper it will be broken as well as the last stage will not be rollback. This is why i choose to go with that approach as for now it ensure that the workflow works. But as you mentioned, we might need to indicate that some how to the users.

At the moment If we create a sub transaction and the user call it with the withTransaction the transaction wrapper will not rollback as well. And if the user call it without the withTransaction then then it will still not rollback the main transaction as it will be catch inside and the manager will be shared as it was previously

@olivermrbl any comment regarding those points?

@olivermrbl
Copy link
Contributor

olivermrbl commented Oct 17, 2022

But i think it is a trade off until we settle on the transaction refactoring to introduce a new pattern

I am not entirely sure, I see the trade-off. From what I understand, adding a serializable child transaction in the work stage would fix the issue and not break the API, so I would immediately think this would be the better choice of the two options here.

Can I get you to elaborate on the issues with that approach? Introducing a new transaction management pattern is still quite far out in the future, so I want to ensure we are making the correct trade-off with that in mind.

@adrien2p adrien2p force-pushed the fix/claim-service-transaction branch from 73afcc9 to ec43c59 Compare October 18, 2022 13:54
@adrien2p
Copy link
Member Author

After discussion with oli, it has been decided to go with that refactoring as it does not create any hidden behaviour and is pretty straight forward and explicit. The changement on the service api will be documented in order for a user to be able to use the idempotency key service properly

@adrien2p adrien2p force-pushed the fix/claim-service-transaction branch from 9e4c6aa to 40e24d6 Compare October 18, 2022 14:41
Copy link
Contributor

@olivermrbl olivermrbl left a comment

Choose a reason for hiding this comment

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

Great work. Can I get you to add a changeset with a minor dump to @medusajs/medusa?

Copy link
Contributor

@olivermrbl olivermrbl left a comment

Choose a reason for hiding this comment

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

LGTM, I've mentioned you in an issue in Linear regarding release content. We'll have to include a short description of this one specifically, as we'll be breaking the API of the idempotency key service.

@olivermrbl olivermrbl merged commit 9deec0f into develop Oct 19, 2022
@olivermrbl olivermrbl deleted the fix/claim-service-transaction branch October 19, 2022 08:47
@github-actions github-actions bot mentioned this pull request Oct 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants