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] external_id is skipped and updates stop if something updates the User (such as addTag) shortly before login is called #2046

Merged
merged 7 commits into from
Apr 10, 2024

Conversation

jkasten2
Copy link
Member

@jkasten2 jkasten2 commented Apr 8, 2024

Description

One Line Summary

Fixes login silently failing (and operations after gets stuck) when login is called within 5 seconds of a user property update (such as addTag).

Details

This fixes a bug where calling addTag() then login() would cause the login to be dropped.
The bug happen on all operations didn't have a create or modify key, this is required so operations are not grouped together when they should not be. Since we fixed batching in 5.1.7 to always wait 5 seconds this issue will be most common on 5.1.7, however all versions back to 5.0.0 are effected.

Motivation

It's critical that login works consistently.

Scope

Affects operation repo grouping and error handling of executors.

How this issue happened

This is becauseSetTagOperation.modifyComparisonKey was always "" which matched LoginUserOperation.modifyComparisonKey as it was also "" and both these operations were returned by OperationRepo.getGroupableOperations. Both operations were given to UpdateUserOperationExecutor which it would skip the LoginUserOperation silently.

Recovering from stalled state

Since the bug was dropping the login operation, it needs to be replaced to get those already in the bad state out. Commit bc91777 does this.

If the commit above was not done then even if the developer called OneSignal.login() again with the same externalId it would not correct the stalled User. Only calling logout() or login() with different externalId would have un-stalled the OperationRepo. And then only after logging back to that stalled User would it have recover all the unsent operations they may exist.

Related PRs

This mistake originated from PR #1794, commit f1d204e, which was shipped in the 5.0.0 (wasn't in 5.0.0-beta4 yet). I preserved the intent of PR #1794, and fixed the mistake in commit 7fe2010.

Related Issues

Testing

Unit testing

Corrected some existing unit tests.

Manual testing

Android 14 Emulator.

  • Fresh install - addTag, login
    • The bug that initially uncovered this issue.
    • Also ensured accepting notification permission updated subscription
  • Fresh install - addTag, login, addTag
    • Ensures the keys for comparison key values are being handled correctly
  • Fresh install - Add and remove an alias back-to-back
    • Confirms assumption that these are split up due to grouping
  • After restarting the app - Logout and login again
  • Fresh install - Device offline, accept notifications, device online, observer subscription is enabled on the dashboard.
  • Fresh install - Delayed starting OperationRepo (artificially with delay) - observer subscription is enabled on the dashboard.
  • Tested recovery code
    • Fresh installed app with 5.1.7
    • Reproduced stalled bug
      • Such as calling OneSignal.User.addTag(), then OneSignal.login() back-to-back
    • Upgraded to this PR
    • Ensured it recovered and it sets the externalId
      • NOTE: There is a backend bug with POST /users, where subscription updates are not being applied so the subscription may stay disabled.

Affected code checklist

  • Notifications
    • Display
    • Open
    • Push Processing
    • Confirm Deliveries
  • Outcomes
  • Sessions
  • In-App Messaging
  • REST API requests
  • Public API changes

Checklist

Overview

  • I have filled out all REQUIRED sections above
  • PR does one thing
    • If it is hard to explain how any codes changes are related to each other then it most likely needs to be more than one PR
  • Any Public API changes are explained in the PR details and conform to existing APIs

Testing

  • I have included test coverage for these changes, or explained why they are not needed
  • All automated tests pass, or I explained why that is not possible
  • I have personally tested this on my device, or explained why that is not possible

Final pass

  • Code is as readable as possible.
    • Simplify with less code, followed by splitting up code into well named functions and variables, followed by adding comments to the code.
  • I have reviewed this PR myself, ensuring it meets each checklist item
    • WIP (Work In Progress) is ok, but explain what is still in progress and what you would like feedback on. Start the PR title with "WIP" to indicate this.

This change is Reviewable

All operations must have at least a create or modify key, this is
required so operations are not grouped together when they should not be.

This fixes a bug where calling addTag() back-to-back with login() would
cause the login to be dropped. This is because
SetTagOperation.modifyComparisonKey was "" which matched
LoginUserOperation.modifyComparisonKey as it was also "" and both these
operations we returned by OperationRepo.getGroupableOperations. Both
operations were given to UpdateUserOperationExecutor which it would skip
the LoginUserOperation silently.

This mistake originated from f1d204e
which wasn't in the 5.0.0-beta4 release, but was introduced in 5.0.0.
The intent of PR #1794 is still preserved in this commit, we just simply
fixed the bug noted above.
@jkasten2 jkasten2 changed the title WIP [Fix] stuck user state if something updates User before (such as addTag) before login is called WIP [Fix] stuck user state if something updates the User (such as addTag) before login is called Apr 8, 2024
To ensure operations are not silently skipped each executor now checks
if it can process all the operations. This is important since bugs can
go unnoticed for a while and without this it's hard to debug too.
@jkasten2 jkasten2 force-pushed the fix/operation-repo-missing-grouping-modify-key branch from d0d2b84 to 20075f7 Compare April 9, 2024 01:10
This test was missed when support for this was droped in commit
f1d204e
This test had an extra update subscription operation.
1. This test shouldn't contain an update since it is testing a delete
2. An update and a delete could never be executed together as it's keys
are different and therefore would never be grouped together.
We want to know if this happens as soon as possible, as it will almost
always result in operations being combined when they should not.
@jkasten2 jkasten2 changed the title WIP [Fix] stuck user state if something updates the User (such as addTag) before login is called [Fix] stuck user state if something updates the User (such as addTag) before login is called Apr 9, 2024
@jkasten2 jkasten2 changed the title [Fix] stuck user state if something updates the User (such as addTag) before login is called [Fix] external_id setting is skipped and stuck user state if something updates the User (such as addTag) shortly before login is called Apr 9, 2024
@jkasten2 jkasten2 changed the title [Fix] external_id setting is skipped and stuck user state if something updates the User (such as addTag) shortly before login is called [Fix] external_id setting is skipped and updates stop if something updates the User (such as addTag) shortly before login is called Apr 9, 2024
@jkasten2 jkasten2 changed the title [Fix] external_id setting is skipped and updates stop if something updates the User (such as addTag) shortly before login is called [Fix] external_id is skipped and updates stop if something updates the User (such as addTag) shortly before login is called Apr 9, 2024
Commit 7fe2010 fixed a bug with login
operations being drop in some scenarios, however it doesn't fix those
already in the bad state.

This comment get us out of the bad state by generating a replacement
LoginUserOperation. See the comments in the code for more details.

This comment was manually tested, ensuring it gets us out of the bad
state, and updates works afterwords.
Copy link
Contributor

@nan-li nan-li left a comment

Choose a reason for hiding this comment

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

I think the commit add operation checks to all executors points out some things we may want to address in a future PR, but this PR to address the issues it is fixing, I approve after testing on my end.

@jkasten2 jkasten2 merged commit 46316e6 into main Apr 10, 2024
2 of 3 checks passed
@jkasten2 jkasten2 deleted the fix/operation-repo-missing-grouping-modify-key branch April 10, 2024 01:50
@jkasten2 jkasten2 mentioned this pull request Apr 10, 2024
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