What are the retry strategy/ mechanism for WorkManager's OneTimeWorkRequest

15,681

Solution 1

The default is BackoffPolicy.EXPONENTIAL. We only retry when you ask us to RETRY by returning WorkerResult.RETRY or when constraints that were required for your Worker are now unmet. So for e.g. if you required a NETWORK constraint, and now the device lost its active Network connection - then the Worker will be stopped and be automatically retried (when the constraints are met).

For more information look at the docs.

Solution 2

This following example retry 3 times on caught Exception before quit.

class RepeatWorker(context : Context, params : WorkerParameters)
    : Worker(context, params) {

    private fun doSomeThing() {
        // do something
    }

    override fun doWork(): Result {

        if (runAttemptCount > 3) {
            return Result.failure()
        }

        try {
            doSomeThing()
        }
        catch (e: Exception) {
            e.printStackTrace()
            return Result.retry()
        }
        return Result.success()
    }
}

NOTE: Default BackoffPolicy is exponential, where 1st retry in 30s (minimum retry period is 10s and maximum retry period never exceed 18000s/5 hours).

fun start() : LiveData<WorkInfo> {
    val WORK_NAME = "SingleBackupWorker"

    val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()

    val work = OneTimeWorkRequestBuilder<BackupWorker>()
            .setConstraints(constraints)
            .setInitialDelay(5, TimeUnit.SECONDS)
            .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 1, TimeUnit.MINUTES)
            .build()

    WorkManager.getInstance().enqueueUniqueWork(WORK_NAME, ExistingWorkPolicy.REPLACE, work)

    return WorkManager.getInstance().getWorkInfoByIdLiveData(work.id)
}

Solution 3

Gets the current run attempt count for any work from runAttemptCount . Note that for periodic work, this value gets reset between periods. Link :-

https://developer.android.com/reference/androidx/work/ListenableWorker#getRunAttemptCount()

example :

override fun doWork(): Result {

    if (runAttemptCount < maxRetryConstantIWant) {
    ..... 
    .....
    .....
    } else { Result.Failure }
}

Here runAttemptCount is worker method.

Share:
15,681

Related videos on Youtube

Lumii
Author by

Lumii

WeNote - Notes, To-do lists, Reminders &amp; Calendar JStock Android JStock - Free Stock Market Software WeFocus - Focus, Pomodoro, Do one thing at a time

Updated on January 25, 2021

Comments

  • Lumii
    Lumii over 3 years

    I have the following one-time worker.

    // Create a Constraints that defines when the task should run
    Constraints constraints = new Constraints.Builder()
            .setRequiredNetworkType(NetworkType.UNMETERED)
            .setRequiresBatteryNotLow(true)
            // Many other constraints are available, see the
            // Constraints.Builder reference
            .build();
    
    OneTimeWorkRequest oneTimeWorkRequest =
            new OneTimeWorkRequest.Builder(SyncWorker.class)
                    .setConstraints(constraints)
                    .addTag(SyncWorker.TAG)
                    .build();
    

    According to https://developer.android.com/topic/libraries/architecture/workmanager

    // (Returning RETRY tells WorkManager to try this task again
    // later; FAILURE says not to try again.)
    

    I was wondering, if SyncWorker keep returning RETRY, what is the retry strategy of WorkManager? For instance, what is the maximum retry count for WorkManager? The documentation isn't clear on this.

  • remedy.
    remedy. over 5 years
    It's weird though because I've had instances where contraints were not met, and after the contraints became met, it would defer the execution of the worker. Any insight on this behavior?
  • sam_k
    sam_k over 5 years
    @remedy you can return RETRY from your doWork method()
  • remedy.
    remedy. over 5 years
    @sam_k I'm aware of the RETRY. I just now realized though that all of these executions are deferred. So even if we do retry, the retry execution will be deferred.
  • sam_k
    sam_k over 5 years
    @remedy ya but it will be executed after some time. do you want to execute something immediately then you must use startForeGroundService
  • Luan
    Luan over 5 years
    @Rahul and how about the scenario when there is a need to retry some unique (named) work just after the last worker in the queue? I have N workers of the same type that may need to retry if some information is not available yet, but if one of them fails, I need to retry it just when the others in the queue could try to take its information first (to avoid the same worker fail "forever" until its specific information is available). Is it possible to design this workflow?
  • RamPrasadBismil
    RamPrasadBismil about 5 years
    But would it keep retrying if nothing changes or stop after 10mins?
  • jiaqi jiang
    jiaqi jiang about 5 years
    Hi, I also want to know if it will keep retrying if it is stoped after 10mins
  • Shivam Pokhriyal
    Shivam Pokhriyal almost 4 years
    Hey where do you get the info about the maximum retry period?
  • Renaud
    Renaud almost 4 years
  • lasec0203
    lasec0203 almost 4 years
    hmm, there really should be an example in the docs about using runAttemptCount to limit the amount of retries