Pztar
Pztar

Reputation: 4749

How to enqueue sequential work without WorkContinuation

Using WorkManager 2.1.0,

How can I enqueue a set of operations without using WorkContinuation? If I have

val firstSet = firstWorkers()
val secondSet = secondWorkers()

How can I execute the secondSet after the firstSet has completed?

I do not want to chain the work as I still want the secondSet to execute even if a call fails within the firstSet


Things I've tried,

enqueue

workManager.enqueue(firstSet)
workManager.enqueue(secondSet)

I would assume the enqueue function would cause the operations to run in order, however they run out of order I'm assuming this is due to multi-threads?

LiveData

workManager.enqueue().state().observe {} and running workManager.enqueue(secondSet) after a SUCCESS

Async/Await

coroutineScope.async { workManager.enqueue().await() }

even though the result is returned sequentially, the network calls still happen out of order, in some cases firstSet doesn't execute until the end.


The only "solution" I could find was to return a Result.success() from the doWork() function even if it fails, that seems wrong.

How can I execute operations sequentially even if one of the previous calls fails?

Upvotes: 2

Views: 924

Answers (1)

pfmaggi
pfmaggi

Reputation: 6476

As you wrote, when you build a WorkCountination, if one of the worker fails, all the chain is marked as failed and the following worker are not executed.

This is also true when you use unique work requests with the APPEND ExistingWorkPolicy; in this case you're also building a chain of work so, if one of the worker fails, all the following worker aren't executed.

I you want to have a guaranteed order, and you don't mind if a previous worker fails I can only think of two solutions:

  1. Always return Result.Success(dataOut) from your worker. You define what is success, for WorkManager a failure in a chain means that everything in the chain needs to fails. This is not what you want so you may add some additional information in the dataOut object.
  2. You enqueue the second worker from inside the first one, independently of its result.

Personally I prefer the first option, you just need to agree on what is success and failure with WorkManager and use the Data object that you return in the Result.Success() call if you need to handle the "unsuccessful" case.

Upvotes: 5

Related Questions