Skip to content Skip to sidebar Skip to footer

Having Coroutine Wait For Previous Calls

I still haven't fully grasped Kotlin coroutines yet. Basically I want a coroutine to wait for any previous calls to finish before executing. The following code seems to work. But i

Solution 1:

Keep in mind that the launched code is concurrent to the code outside it. That means that what you wrote has a race condition: the outside code may have already assigned the new job to saveJob when you try to join() it, resulting in a deadlock.

I guess what you want is to trigger a save operation in the background, and the operation itself will pull all the data to save from somewhere else. You probably don't want a queue of save jobs, just ensure that everything is saved at the point you call save(). If you called save a bit earlier and a new save job hasn't yet started, those two calls can be coalesced into a single save operation.

Furthermore, you say that you have a suspending database operation. Suspending code doesn't belong in the IO dispatcher, which is there only if you have to perform many blocking operations concurrently.

All told I'd suggest using an actor:

val actor = someScope.actor<Unit>(capacity = CONFLATED) {
    // suspending database operation
}

funsave() = someScope.launch {
    actor.send(Unit)
}

Solution 2:

Basically it's not wrong. Although I would recommend just to go imperatively just as you program outside of a coroutine. Saving the response in the variable would ensure that the next line won't execute until the response of the first:

scope.launch(someDispatcher){
  val dataFromDelayingCode = getDelayingData()
  if(delayingData.isFinished){

  }
}

Post a Comment for "Having Coroutine Wait For Previous Calls"