The name of APPEND_OR_REPLACE
is misleading, by reading this you will think that this Worker
will REPLACE the previous worker in case of failure, or APPEND if it is RUNNING, which is wrong!
APPEND_OR_REPLACE
means APPEND this worker to the running chain OR REPLACE the chain with a new one if the previous failed (create a new chain and start over, it is like a hard reset)
pseudo code
if (getChainWithUniqueTag(TAG).status == CANCELLED || FAILED) {
createNewChine()
}
addRequestToChainWithTag(TAG,request)
Now It should make more sense, it is about the state of current chain and not the Work
To confirm this more, try to start a worker1 with a unique name, and then fail it (by calling Result.failure
) and then create another worker2 with APPEND
with the same unique name, worker2
will fail directly before starting because it belongs to a failing chain.
If you try the same scenario but with APPEND_OR_REPLACE
, worker2
will start a new chain and continue working normally.
Consider this example :
val request1 = OneTimeWorkRequestBuilder<SleepWorker>()
.setInputData(workDataOf(KEY_BREAK_AT to 5))
.build()
val request2 = OneTimeWorkRequestBuilder<SleepWorker>()
.build()
workManager.enqueueUniqueWork(
TAG,
ExistingWorkPolicy.APPEND_OR_REPLACE,
request1
)
// Infinite loop
while (workManager.getWorkInfoById(request1.id).get().state == WorkInfo.State.RUNNING){}
workManager.enqueueUniqueWork(
TAG,
ExistingWorkPolicy.APPEND_OR_REPLACE,
request2
)
SleepWorker
class SleepWorker(context: Context, parameters: WorkerParameters) :
CoroutineWorker(context, parameters) {
override suspend fun doWork(): Result {
val breakAt = inputData.getInt(KEY_BREAK_AT,-1)
repeat(10) {
if(it == breakAt) return Result.failure()
println("$it")
delay(1000L)
}
return Result.success()
}
}
Now in this case, request1
will fail, and then we start request2
and it will starts normally, because the FLAG is APPEND_OR_REPLACE
,
If the flag is APPEND
then request2
will fail.
PS: try to move the second enqueueUniqueWork
for request2
before the infinite while
loop, request2
will fail too. makes sense no ?
because when we called enqueueUniqueWork
the chain was good at that time, and for that the job has been added to that chain successfully.