-
Notifications
You must be signed in to change notification settings - Fork 371
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] grouping skipping opRepoPostCreateDelay, causing operations being applied out of order when multiple login operations are pending. (fixes issue since 5.1.10) #2087
Conversation
Added test to prove that grouping logic is not waiting on opRepoPostCreateDelay for new ids.This has side effect of operations being done out of order in some cases. A real world case is login operations can be done out of order, which also results in things like the push subscription being on the wrong users. There is also a smaller issue where we are simply not waiting the time limit so some 404 error were not being avoid but would have still resulted in correct behavior in the end.
opRepoPostCreateDelay like OperationRepo.getNextOps(), this would lead to some being applied out of order. The only known case is when there is a login in the queue for an Anonymous User crate and also User A and another for User B. The anonymous User create happens first with a push subscription which is correct. Then we have to wait for opRepoPostCreateDelay time after that create before we can attempt to identify it has User A, this is also ok. However we skip to User B and try to create it and transfer the subscription, this isn't correct as we also should wait opRepoPostCreateDelay for the new subscription id. While this commit fixes the issue noted above there should be another mechanism in place to prevent such an issue. This should be done in a follow up commit. See PR #2087 for more details.
Reversing the list means we insert each item at index 0 to keep the order correct. Always inserting at index 0 means we no longer need to keep an index state, which both simples the code but also means we don't depend on state which may be wrong sometimes, noted in the warning comment that was removed in this commit. This reversed() logic for list used in a few places in this file already to solve this problem.
I'm seeing if user The response is parsed and the ID for the email subscription is extracted as the push subscription ID, which has odd side effects of being transferred to user B and the ID used to update the push subscription. Perhaps because the email was the first item in the returned subscriptions array, the push sub was the second item. UPDATE: Looks like an existing issue if a CreateUser is sent with an email subscription, not related to this PR. |
I'm testing this flow on a new install with network off: // Init OneSignal
// Anon user creation
OneSignal.login("<EXISTING_EUID_USER_A");
OneSignal.getUser().addTag("a", "a");
OneSignal.login("B");
OneSignal.getUser().addEmail("b@b.com"); Then turn network on. There's some unexpected ordering and requests made, but eventually everything ends up in the mostly correct states, it seems.
|
Looking at this scenario again 👆, I think the issue is that for User B, there are 3 operations enqueued:
However, since |
Since opRepoPostCreateDelay is passed to delay() canAccess() should use inclusive logic.
The OperationRepo can't juggle two different users correctly, so stall the whole queue by opRepoPostCreateDelay. We plan to address this limitation in a future PR.
Description
One Line Summary
Fix operations being applied out of order when multiple login operations are pending.
Details
OperationRepo.getGroupableOperations()
was not respectingopRepoPostCreateDelay
likeOperationRepo.getNextOps()
, this would lead to some being applied out of order. The only known case is when there is a login in the queue for an Anonymous User crate and also User A and another for User B. The anonymous User create happens first with a push subscription which is correct. Then we have to wait for opRepoPostCreateDelay time after that create before we can attempt to identify it has User A, this is also ok. However we skip to User B and try to create it and transfer the subscription, this isn't correct as we also should waitopRepoPostCreateDelay
for the new subscription id.We addressed
getGroupableOperations()
in this PR however it was not enough, the OperationRepo and it's executors still ran into edge cases where ids would get mixed up due to intermixing of operations on different users. So in this PR we consistently stall the whole OperationRepo processing to avoid the issues, until we can make a flow up PR to improve this later.While this PR fixes the issue noted above there should be another mechanism in place to prevent such an issue. This should be done in a follow up PR.
Motivation
No matter how quickly or the offline state of the device operations should be applied in the correct order.
Scope
Corrects
OperationRepo
ordering and makes now consistently delays the OperationRepo after creating records.Related
This is a follow up to PR #2059, where that logic created the issue noted above.
Testing
Unit testing
Manual testing
Tested on Android 6 with the following scenario:
OneSignal.login("A")
OneSignal.User.addEmail("a@a.com")
OneSignal.User.addTag("a", "a")
OneSignal.login("B")
OneSignal.User.addEmail("b@b.com")
OneSignal.User.addTag("b", "b")
Affected code checklist
Checklist
Overview
Testing
Final pass
This change is