fix(invoice): Fix race-condition in invoice update jobs #3851
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.
Context
When doing a manual payment, it will update the invoice payment status. When doing so, we're supposed to do a few things asynchronously like sending a webhook.
Unfortunately, the way it is working right now, our server will sometimes process those asynchronous jobs before the database transaction ends, and therefore before we actually update the invoice. We end up with not up-to-date data within those different actions.
For instance, the webhook might be triggered with
payment_status: 'pending'
in the payload instead ofpayment_status: 'succeeded'
.Description
This commit fixes this issue by ensuring the jobs run after the transaction is committed. This is done by using
AfterCommitEverywhere.after_commit
callbacks.To reduce the risk of mistakes, two new class methods were added:
ApplicationJob.perform_after_commit
Utils::ActivityLog.produce_after_commit
Doing this, we make the intention clear that the job should run after the transaction is committed.
Test were added for the new methods, and existing tests were updated to properly test that jobs are enqueued after the transaction is committed. To do so, a
expect {}.to enqueue_after_commit
matcher was added.