diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/impl/OperationRepo.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/impl/OperationRepo.kt index 23a284ebcd..a17fdf401b 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/impl/OperationRepo.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/impl/OperationRepo.kt @@ -25,6 +25,7 @@ internal class OperationRepo( private class OperationQueueItem( val operation: Operation, val waiter: WaiterWithValue? = null, + var retries: Int = 0, ) private val executorsMap: Map @@ -200,10 +201,18 @@ internal class OperationRepo( } } ExecutionResult.FAIL_RETRY -> { + Logging.error("Operation execution failed, retrying: $operations") // add back all operations to the front of the queue to be re-executed. + var highestRetries = 0 synchronized(queue) { - ops.reversed().forEach { queue.add(0, it) } + ops.reversed().forEach { + if (++it.retries > highestRetries) { + highestRetries = it.retries + } + queue.add(0, it) + } } + delayBeforeRetry(highestRetries) } ExecutionResult.FAIL_PAUSE_OPREPO -> { Logging.error("Operation execution failed with eventual retry, pausing the operation repo: $operations") @@ -237,6 +246,13 @@ internal class OperationRepo( } } + suspend fun delayBeforeRetry(retries: Int) { + val delayFor = retries * 15_000L + if (delayFor < 1) return + Logging.error("Operations being delay for: $delayFor") + delay(delayFor) + } + /** * Given a starting operation, find and remove from the queue all other operations that * can be executed along with the starting operation. The full list of operations, with diff --git a/OneSignalSDK/onesignal/core/src/test/java/com/onesignal/core/internal/operations/OperationRepoTests.kt b/OneSignalSDK/onesignal/core/src/test/java/com/onesignal/core/internal/operations/OperationRepoTests.kt index 51746c1a60..e0d542b690 100644 --- a/OneSignalSDK/onesignal/core/src/test/java/com/onesignal/core/internal/operations/OperationRepoTests.kt +++ b/OneSignalSDK/onesignal/core/src/test/java/com/onesignal/core/internal/operations/OperationRepoTests.kt @@ -16,6 +16,7 @@ import io.mockk.just import io.mockk.mockk import io.mockk.runs import io.mockk.slot +import io.mockk.spyk class OperationRepoTests : FunSpec({ @@ -73,7 +74,15 @@ class OperationRepoTests : FunSpec({ every { mockOperationModelStore.remove(any()) } just runs val operationRepo = - OperationRepo(listOf(mockExecutor), mockOperationModelStore, MockHelper.configModelStore(), MockHelper.time(1000)) + spyk( + OperationRepo( + listOf(mockExecutor), + mockOperationModelStore, + MockHelper.configModelStore(), + MockHelper.time(1000), + ), + ) + coEvery { operationRepo.delayBeforeRetry(any()) } just runs val operationIdSlot = slot() val operation = mockOperation(operationIdSlot = operationIdSlot) @@ -93,6 +102,7 @@ class OperationRepoTests : FunSpec({ it[0] shouldBe operation }, ) + operationRepo.delayBeforeRetry(1) mockExecutor.execute( withArg { it.count() shouldBe 1