@@ -163,22 +163,32 @@ internal class OperationRepo(
163
163
/* *
164
164
* Waits until a new operation is enqueued, then wait an additional
165
165
* 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.
166
176
*/
167
177
private suspend fun waitForNewOperationAndExecutionInterval () {
168
178
// 1. Wait for an operation to be enqueued
169
179
var wakeMessage = waiter.waitForWake()
170
180
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.
175
184
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
182
192
}
183
193
}
184
194
0 commit comments