https://kotlinlang.org logo
#coroutines
Title
# coroutines
t

Tim Malseed

01/04/2021, 6:23 AM
I have an
Actor
, and I'd like to be able to remove/cancel an operation when a new one comes in, depending on the progress of the previous operation.
Copy code
private val actor = scope.actor<AdapterOperation>(capacity = Channel.CONFLATED) {
        for (operation in channel) {
            when (operation) {
                is AdapterOperation.Update -> updateInternal()
                ...
            }
        }
    }
Copy code
private suspend fun updateInternal() {
    withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
        val result = performSomeLongRunningTask()
    }
    
    // Todo:
    // If our long running task has completed, then continue. 
    // But if a new update has been queued and we haven't reached
    // this point, then cancel this operation.

    if (coroutineContext.isActive) {
        withContext(Dispatchers.Main) {
            applyResultOfLongRunningTask(result)
        }
    }
}
So, if a new
Update
operation is sent, then any previous
Update
operation in the queue, which has not reached a certain point (see code comment above), would be cancelled/removed from the queue
I'm not sure whether this makes any sense, and if it does - how one might solve this problem
t

tseisel

01/04/2021, 12:57 PM
I've already had this kind of problem. I solved it by having the actor launch a child coroutine:
Copy code
scope.actor<Input> {
  var job: Job? = null
  for (input in channel) {
    job?.cancel()
    job = launch { /* some lengthy operation */ }
  }
}
👍 1
t

Tim Malseed

01/05/2021, 4:45 AM
Thanks for this
7 Views