Use transaction to update data when joining challenge #15253
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #8337
Changes
This PR fixes an issue where the member count listed on a challenge's page (which is taken from the challenge's document in the database) can be incorrect.
This issue occurred because of two separate database calls that occur when a user joins a challenge. In particular, the
challenge.addToUser(user)
method and thechallenge.save()
methods are what conspired to cause this issue.Since
challenge.addToUser(user)
actually modifies the user document as a separate database call, if this were to succeed and subsequently thechallenge.save()
were to fail, there would be a mismatch in the participants of the challenge (see this comment for reference).In looking into this, I noticed that this issue was probably mitigated by PR #11502, where the author added a check to make sure the
User
document had actually been modified before proceeding with saving the challenge. Prior to that, it was likely thatchallenge.addToUser(user)
would sometimes fail but subsequentlychallenge.save()
succeeded, leading to the original issue.My solution includes all the relevant database calls in a single transaction, so that if any query should fail then no part of the User or Challenge documents will be modified. I've maintained the current functionality as much as possible so as to minimize the impact this change has. The primary change that is happening here is to wrap several database calls into a a single mongoose session/transaction.
Habitica user UUID: d419ade0-fb52-4fec-890b-905a75a4fa1c