joney
07/24/2023, 4:02 PMclass Worker(
private val scope: CoroutineScope,
) {
private var job1: Job? = null
private var job2: Job? = null
fun doWork1() {
job1?.cancel()
job1 = scope.launch { /* do work */ }
}
fun doWork2() {
job2?.cancel()
job2 = scope.launch { /* do work */ }
}
}
Is there a smarter way or a shortcut for this common job cancel & assign ceremony?franztesca
07/24/2023, 4:18 PMclass Worker(
private val scope: CoroutineScope,
) {
private val job1 = scope.restartableJob {
job1Impl()
}
private val job2 = scope.restartableJob {
job2Impl()
}
fun doWork1() {
job1.restart()
}
fun doWork2() {
job2.restart()
}
}
interface RestartableJob: Job {
fun restart()
}
fun CoroutineScope.restartableJob(
block: suspend CoroutineScope.() -> Unit,
): RestartableJob {
val channel = Channel<Unit>(Channel.CONFLATED)
val job = launch {
channel.consumeAsFlow().collectLatest { block() }
}
return object : RestartableJob, Job by job {
override fun restart() {
channel.trySend(Unit)
}
}
}
joney
07/25/2023, 1:44 PMclass CancelAndLaunch {
private var job: Job? = null
suspend operator fun invoke(
block: suspend () -> Unit,
) = coroutineScope {
job?.cancelAndJoin()
job = launch { block() }
}
}