Conversation
This commit simply adds a test to prove the following issue with the current implementation of OperationRepo. Once processQueueForever starts processing operations it will execute them back-to-back until it can't process any more. This is done intently as the idea is sync all changes to the backend quickly, after waiting a set amount of time for batching. However nothing is in place to account for something continually adding new operations to the repo while it's in this mode. Some misbehaving app could be adding operations in a tight loop as fast or faster than the queue could exclude them.
7788f3d to
0988977
Compare
Buckets Purpose: Bucketing is a pattern we are using to help save network calls. It works together with opRepoExecutionInterval to define a time window operations can be added to the bucket. When enqueue() is called it creates a new OperationQueueItem with it's bucket = enqueueIntoBucket. Just before we start processing a bucket we enqueueIntoBucket++, this ensures anything new that comes in while executing doesn't cause it to skip the opRepoExecutionInterval delay. NOTE: Bucketing only effects the starting operation we grab. The reason is we still want getGroupableOperations() to find other operations it can execute in one go (same network call). It's more efficient overall, as it lowers the total number of network calls. This address the failing test "operations enqueued while repo is executing should be executed only after the next opRepoExecutionInterval" we added in commit 0988977
5c3f1b7 to
0f718b7
Compare
This ensures we don't have a off-by-one errors
We want to ensure we are processing operations starting operations we didn't process the last time the app was running and in an efficient way.
nan-li
approved these changes
Apr 15, 2024
Contributor
nan-li
left a comment
There was a problem hiding this comment.
Tested manually by enqueuing lots of addTags while operations are executing and requests are made every second or less. After PR changes, spam enqueuing makes requests every 5 seconds only.
Also tested with device offline, cached operations and any cached operation items initialize with bucket = 0. Behavior appears correct.
jinliu9508
approved these changes
Apr 15, 2024
Contributor
jinliu9508
left a comment
There was a problem hiding this comment.
Manually tested with increment of bucket ensuring the logic works correctly. Also tested other normal operations including login, push, logout to make sure it doesn't break existing features.
Member
Author
|
@nan-li @jinliu9508 appreciate both of you testing as well! And for the code review |
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Description
One Line Summary
Fixes new operations added to
OperationRepo's queue while its executing from skipping theopRepoExecutionIntervaldelay.Details
Motivation
Preventing a misbehaving app adding operations (such as addTag()) in a tight loop, causing a number of back-to-back network calls to OneSignal's backend.
Scope
Only affects
OperationRepo's batching logic.New OperationRepo Concept - Buckets
Future Considerations
There is still a problem if someone rapidity adds login operations which switches users. (such calling
login()with different external_ids, orlogin()andlogout()over and over). They would all be in the same bucket and each would be its own network call and we would call them back-to-back without a delay. This isn't a problem with things like addTag, since those can be grouped into one network call.Ideas to address this:
Related
This improves on the PR #2033, which fixed
opRepoExecutionIntervalfrom being skipped anytime two operations were called back-to-back.Testing
Unit testing
Manual testing
Manually tested on an Android 14 emulator, tested to ensure prompting for notifications works and updates the subscription correctly. As well as logging into a new user.
Also tested running the following code no longer reproduces the orignal issue:
Affected code checklist
Checklist
Overview
Testing
Final pass
This change is