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

addresses a possible race condition with purchase completed callbacks #313

Merged
merged 2 commits into from
Aug 11, 2020

Conversation

aboedo
Copy link
Member

@aboedo aboedo commented Aug 10, 2020

There was a race condition in handleReceiptPostWithTransaction:purchaserInfo:subscriberAttributes:error:.

The issue was that in the order of operations, we were:

  1. fetching the completion block
  2. performing the completion block
  3. removing it from the callbacks list.

If the completion block performed in 2. does something like initiate another purchase, it would access the callbacks list before it got removed in 3, and then the code would see that there's already a completion block for the product and return the RCOperationAlreadyInProgressError.

might address #291, but it's not guaranteed to since I'm not sure that this was the original issue.

@aboedo aboedo requested a review from vegaro August 10, 2020 23:02
@aboedo aboedo self-assigned this Aug 10, 2020
Comment on lines +1982 to +1985
self.purchases!.purchasePackage(package) { _,_,_,_ in
self.purchases!.purchasePackage(package) { (tx, info, error, userCancelled) in
receivedError = error as NSError?
secondCompletionCalled = true
Copy link
Member Author

Choose a reason for hiding this comment

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

this is the error case - while the completion block is running, it hasn't been removed from the list of completion blocks, and so initiating a new purchase will fail.
I confirmed that this test fails on develop

Copy link
Contributor

Choose a reason for hiding this comment

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

good catch!

Comment on lines +1982 to +1985
self.purchases!.purchasePackage(package) { _,_,_,_ in
self.purchases!.purchasePackage(package) { (tx, info, error, userCancelled) in
receivedError = error as NSError?
secondCompletionCalled = true
Copy link
Contributor

Choose a reason for hiding this comment

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

good catch!

@synchronized (self) {
completion = self.purchaseCompleteCallbacks[transaction.payment.productIdentifier];
self.purchaseCompleteCallbacks[transaction.payment.productIdentifier] = nil;
Copy link
Contributor

Choose a reason for hiding this comment

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

thanks for fixing the productIdentifier thing, that was bad from me

if (productIdentifier) {
self.purchaseCompleteCallbacks[productIdentifier] = nil;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

It's funny, this is exactly what you said the other day that could break

@vegaro vegaro added this to the 3.6.1 milestone Aug 11, 2020
@aboedo aboedo merged commit bdf5d1f into develop Aug 11, 2020
@aboedo aboedo deleted the fix/race_condition_with_purchase_completed_callbacks branch August 11, 2020 15:54
@aboedo aboedo mentioned this pull request Aug 27, 2020
@aboedo aboedo mentioned this pull request Sep 10, 2020
@aboedo aboedo modified the milestones: 3.6.1, 3.6.2, 3.6.0 Oct 5, 2020
@aboedo aboedo mentioned this pull request Jul 13, 2021
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.

2 participants