What are differences between BackoffPolicy.EXPONENTIAL and BackoffPolicy.LINEAR when working with Work Manager?
Asked Answered
M

3

11

There is no any official doc (as I have read the docs at least) that explain the usage and the mechanism behind these two modes . How do they work ? And what problem do they solve ?

I will appreciate that if anyone can simplified it for me , because I have tested both and have not seen any interesting thing . If you ask me , I would say that OneTimeWorkRequest.setBackoffCriteria() does not affect to the work .

Here are my codes ,

@Override
public void doSomethingUseful(String order) {

    Constraints constraint = new Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build();

    Data data = new Data.Builder()
            .putString("order", order)
            .build();

    OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(OrderSenderWorker.class)
            .setConstraints(constraint)
            .setInputData(data)
            .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 15, TimeUnit.SECONDS)
            .build();

    WorkManager.getInstance().beginUniqueWork("refresh-order", ExistingWorkPolicy.REPLACE, oneTimeWorkRequest).enqueue();

}

And in Worker class whenever I get something wrong , I do return WorkerResult.RETRY in doWork() method.

Thanks in advance .

Mindszenty answered 25/9, 2018 at 10:47 Comment(0)
S
13

Taking into account that the WorkManager uses the run attempt count as reference, for a BackoffPolicy of 15 seconds, will be as next:

  • For linear: work start time + (15 * run attempt count)

  • For exponential: work start time + Math.scalb(15, run attempt count - 1)

The work start time, is when the work was first executed (the 1st run attempt).

Run attempt count is how many times the WorkManager has tried to execute an specific Work.

Also note that the maximum delay will be capped at WorkRequest.MAX_BACKOFF_MILLIS.

Take into consideration that a retry will only happen if you specify that the Work requires it by returning WorkerResult.RETRY

Senior answered 25/9, 2018 at 11:39 Comment(12)
You explained the most part , but if I set to LINEAR and delay is 15 second , it does mean every 15 second the work manager tries to retry my task automatically . Is that right ?Mindszenty
So for linear will retry at 15 seconds multiplied by the total run attempts, and added to the work start time. The retry will happen automatically only if you finish the Work by returning a WorkerResult.RETRY status. If you don't want to retry an specific work then return WorkerResult.SUCCESS or FAILURE.Senior
Yeah I do return WorkerResult.RETRY , but my task does not retry automatically every 15 seconds . Did I something wrong in my code ?Mindszenty
If you want a Work to run every 15s then instead you need to use a PeriodicWorkRequest. The setBackoffCriteria is used for when you need to specify at which rate to retry if the Work fails. If in your code logic you consider that because of whatever reasons the Work has failed (there is no internet, no disk space, etc), then you return a RETRY status, and the WorkManager will use the BackoffCriteria to compute the next retry, which is never at a constant rate because the delay (exponential or linear) will be multiplied by the run attempt count. Let me know if I didn't understand you right.Senior
Yeah my purpose for this certain situation is retry and I do return WorkerResult.RETRY . I have been waiting for at least one automatically retry since I started chatting with you , but nothing has happened :(Mindszenty
In addition when I turn off and then on the Internet it does retry the task but BackoffPolicy still does not work .Mindszenty
I see you have a ExistingWorkPolicy.REPLACE in your code. Make sure to wait and not execute this code logic again before the retry, because the ExistingWorkPolicy.REPLACE will make the previous enqueued work to be discarded, hence no 15s retry. Also just to be sure, get the latest WorkManager version. In addition, as explained, it will never happen every 15s, it will happen 15s * how many times the work has been retried (for lienar), and for Exponential will be even longer.Senior
Forgot to mention, setBackoffCriteria does nothing if you don't return WorkerResult.RETRY. So the best thing to do is to set some traces and debug if you return WorkerResult.RETRY when you expect it. And remember, it will not happen every 15 seconds, check the answer formulas to understand how the retry time is computed.Senior
Dear , I am taking your time , but believe me I do return WorkerResult.RETRY , I traced it , if I did not return RETRY , when I switch off and on the Internet , it would not retry the task . My problem is this BackOff is never invoked .Mindszenty
Did you get the latest WorkManager version? There was a bug reported about this which has bee set already as fixed: issuetracker.google.com/issues/112929917Senior
Thanks . I updated it . I will tell you the result .Mindszenty
Thank you a lot the problem was the Work Manager dependency . Updated it to 'android.arch.work:work-runtime:1.0.0-alpha09' Thanks for spending your time and guiding me manMindszenty
S
1

Consider if you are hitting an API on server if server return specific status you hit the API again after some amount of time.

Now to control the interval time between any two API call, you can use BackoffPolicy.

If you use BackoffPolicy.LINEAR then the interval time will be increased linearly until the threshold reached.

or if you use BackoffPolicy.EXPONENTIAL then the interval time will be increased exponential until the threshold reached.

Susysuter answered 25/9, 2018 at 11:10 Comment(4)
Does your threshold mean the maximum backoff delay duration ?Mindszenty
As you can see my code , based on your declaration my threshold is 15 second and my retry strategy must be stopped after 15 second , right ? But it does continue retrying after 15 second .Mindszenty
here 15 is not the maximum backoff deley. setBackoffCriteria(backoffPolicy: BackoffPolicy, backoffDelay: Long, timeUnit: TimeUnit) Its backoffdeley means the interval time start from 15 and increase exponential.Susysuter
@Susysuter What the threshold time it can be exactly or it is defined based on our time configuration?Thionate
M
0

setBackoffCriteria(BackoffPolicy.LINEAR, 10, TimeUnit.SECONDS)

LINEAR
in case of failure the first launch waits 10s, second launch 10s + 10s wait 20s, third launch 20s + 10s wait 30s, fourth launch 30s + 10s wait 40s etc.
As a result 10s are always added to the last delay.
EXPONENTIAL
in case of failure the first launch waits 10s, second launch 10s * 2 wait 20s, third launch 20s * 2 wait 40s, fourth launch 40s * 2 wait 80s etc.
As a result, the last delay always doubles.
If the conditions are not active for example WI-FI, the task is waiting for the condition to become active and starts.
Maximum time for postponing a task is 5 hours

This method is also used JobInfo for JobService, because WorkManager this is a library to work with all types of services.
setBackoffCriteria(TimeUnit.SECONDS.toMillis(10), JobInfo.BACKOFF_POLICY_LINEAR)

Metanephros answered 10/8 at 15:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.