Skip to content

Commit b6b60c6

Browse files
committed
restart wait time on every OperationRepo.enqueue()
Every time something new is enqueued we will not restart waiting for batches timer. The motivation is to prevent a misbehaving app from continuously making network calls. We are basically saying wait for the "the dust to settle" or "the water is calm" to ensure the app is done making updates. FUTURE: Highly recommend not removing this "the dust to settle" logic, as it ensures any app stuck in a loop can't cause continuous network requests. If the delay is too long for legitimate use-cases then allow tweaking the opRepoExecutionInterval value or allow commitNow() with a budget.
1 parent 39a8b52 commit b6b60c6

File tree

1 file changed

+20
-10
lines changed
  • OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/impl

1 file changed

+20
-10
lines changed

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/impl/OperationRepo.kt

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,22 +163,32 @@ internal class OperationRepo(
163163
/**
164164
* Waits until a new operation is enqueued, then wait an additional
165165
* amount of time afterwards, so operations can be grouped/batched.
166+
* NOTE: Any operations that are enqueued while waiting here causes
167+
* the wait timer to restart over. This is intentional, we
168+
* are basically wait for "the dust to settle" / "the water
169+
* is calm" to ensure the app is done making updates.
170+
* FUTURE: Highly recommend not removing this "the dust to settle"
171+
* logic, as it ensures any app stuck in a loop can't
172+
* cause continuous network requests. If the delay is too
173+
* long for legitimate use-cases then allow tweaking the
174+
* opRepoExecutionInterval value or allow commitNow()
175+
* with a budget.
166176
*/
167177
private suspend fun waitForNewOperationAndExecutionInterval() {
168178
// 1. Wait for an operation to be enqueued
169179
var wakeMessage = waiter.waitForWake()
170180

171-
// 2. Wait at least the time defined in opRepoExecutionInterval
172-
// so operations can be grouped, unless one of them used
173-
// flush=true (AKA force)
174-
var lastTime = _time.currentTimeMillis
181+
// 2. Now wait opRepoExecutionInterval, restart the wait
182+
// time everytime something new is enqueued, to ensure
183+
// the dust has settled.
175184
var remainingTime = _configModelStore.model.opRepoExecutionInterval - wakeMessage.previousWaitedTime
176-
while (!wakeMessage.force && remainingTime > 0) {
177-
withTimeoutOrNull(remainingTime) {
178-
wakeMessage = waiter.waitForWake()
179-
}
180-
remainingTime -= _time.currentTimeMillis - lastTime
181-
lastTime = _time.currentTimeMillis
185+
while (!wakeMessage.force) {
186+
val waitedTheFullTime =
187+
withTimeoutOrNull(remainingTime) {
188+
wakeMessage = waiter.waitForWake()
189+
} == null
190+
if (waitedTheFullTime) break
191+
remainingTime = _configModelStore.model.opRepoExecutionInterval
182192
}
183193
}
184194

0 commit comments

Comments
 (0)