Skip to content

Commit c371096

Browse files
authored
Merge pull request #2017 from OneSignal/feat/add_backoff_to_operation_retries
[Feat] Add backoff to OperationRepo when retrying network calls
2 parents a557800 + 591098c commit c371096

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ internal class OperationRepo(
2525
private class OperationQueueItem(
2626
val operation: Operation,
2727
val waiter: WaiterWithValue<Boolean>? = null,
28+
var retries: Int = 0,
2829
)
2930

3031
private val executorsMap: Map<String, IOperationExecutor>
@@ -200,10 +201,18 @@ internal class OperationRepo(
200201
}
201202
}
202203
ExecutionResult.FAIL_RETRY -> {
204+
Logging.error("Operation execution failed, retrying: $operations")
203205
// add back all operations to the front of the queue to be re-executed.
206+
var highestRetries = 0
204207
synchronized(queue) {
205-
ops.reversed().forEach { queue.add(0, it) }
208+
ops.reversed().forEach {
209+
if (++it.retries > highestRetries) {
210+
highestRetries = it.retries
211+
}
212+
queue.add(0, it)
213+
}
206214
}
215+
delayBeforeRetry(highestRetries)
207216
}
208217
ExecutionResult.FAIL_PAUSE_OPREPO -> {
209218
Logging.error("Operation execution failed with eventual retry, pausing the operation repo: $operations")
@@ -237,6 +246,13 @@ internal class OperationRepo(
237246
}
238247
}
239248

249+
suspend fun delayBeforeRetry(retries: Int) {
250+
val delayFor = retries * 15_000L
251+
if (delayFor < 1) return
252+
Logging.error("Operations being delay for: $delayFor")
253+
delay(delayFor)
254+
}
255+
240256
/**
241257
* Given a starting operation, find and remove from the queue all other operations that
242258
* can be executed along with the starting operation. The full list of operations, with

OneSignalSDK/onesignal/core/src/test/java/com/onesignal/core/internal/operations/OperationRepoTests.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import io.mockk.just
1616
import io.mockk.mockk
1717
import io.mockk.runs
1818
import io.mockk.slot
19+
import io.mockk.spyk
1920

2021
class OperationRepoTests : FunSpec({
2122

@@ -73,7 +74,15 @@ class OperationRepoTests : FunSpec({
7374
every { mockOperationModelStore.remove(any()) } just runs
7475

7576
val operationRepo =
76-
OperationRepo(listOf(mockExecutor), mockOperationModelStore, MockHelper.configModelStore(), MockHelper.time(1000))
77+
spyk(
78+
OperationRepo(
79+
listOf(mockExecutor),
80+
mockOperationModelStore,
81+
MockHelper.configModelStore(),
82+
MockHelper.time(1000),
83+
),
84+
)
85+
coEvery { operationRepo.delayBeforeRetry(any()) } just runs
7786

7887
val operationIdSlot = slot<String>()
7988
val operation = mockOperation(operationIdSlot = operationIdSlot)
@@ -93,6 +102,7 @@ class OperationRepoTests : FunSpec({
93102
it[0] shouldBe operation
94103
},
95104
)
105+
operationRepo.delayBeforeRetry(1)
96106
mockExecutor.execute(
97107
withArg {
98108
it.count() shouldBe 1

0 commit comments

Comments
 (0)