Android Worker Max Retries
Background : While working with WorkManager on Android if there is a handled exception within doWork() we can ask the WorkManager to retry the work and consequently the doWork() will get executed again .
So when will the work get executed again ? Back-Off Policy (as long as Work Constraints are met)
Use case : The work kept on retrying on every interval (indefinitely) as computed through the Back-Off Policy. I wanted to make sure that after five retries the work fails and we log that failure appropriately.
I also wanted to make sure all unit and integration tests passed.
Solution:
Even though there is no direct API to set Max retries (to five in my case) there is a method in WorkParameters getRunAttemptCount() . This “Gets the current run attempt count for this work. Note that for periodic work, this value gets reset between periods.”
Note that runAttemptCount starts from 0
Sample CoroutineWorker doWork method -
override suspend fun doWork(): Result {
return if (runAttemptCount < 5) { // runAttemptCount starts from 0
try {
// do long running work
} catch (ex: IOException) {
Result.retry()
}
Result.success()
} else {
Result.failure()
}
}
Testing :
use
TestListenableWorkerBuilder
to testCoroutineWorker
implementations, as thework-testing
artifact uses Dispatchers.Default rather than your worker implementation’s CoroutineDispatcher
Unit Tests for coroutine worker with MAX_RETRIES
@Test
fun testWorkerSucceedsIfRunAttemptIsLessThanMax() {
val worker = TestListenableWorkerBuilder<LongRunningWorker>(
context = ApplicationProvider.getApplicationContext(),
runAttemptCount = MAX_RETRIES - 1
).build()
runBlocking {
val result = worker.doWork()
assertThat(result, `is`(ListenableWorker.Result.Success()))
}
}
@Test
fun testWorkerFailsIfRunAttemptIsAtMax() {
val worker = TestListenableWorkerBuilder<LongRunningWorker>(
context = ApplicationProvider.getApplicationContext(),
runAttemptCount = MAX_RETRIES
).build()
runBlocking {
val result = worker.doWork()
assertThat(result, `is`(ListenableWorker.Result.Failure()))
}
}
Sample Code on Git
https://github.com/ChaitanyaDuse/WorkManagerSamples
Resources