I’ve been migrating some code from the experimental coroutines to the release version and I find I have to add the same few lines of code to most my classes that spawn new coroutines to make them all CoroutineScoped.
It goes something like this:
class ExampleBefore : CoroutineScope {
private val job = Job()
override val coroutineContext: CoroutineContext get() = job + Dispatchers.IO
}
Or another dispatcher depending on the class’ needs.
Since I’m lazy and hate duplicating this code around I made myself a new interface for this and a default implementation intended for use as a delegate implementation of the scope interface.
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlin.coroutines.CoroutineContext
interface CoroutineScopeAndJob : CoroutineScope {
val job: Job
}
class JobBasedScope(val dispatcher: CoroutineDispatcher) : CoroutineScopeAndJob {
override val job = Job()
override val coroutineContext: CoroutineContext get() = job + dispatcher
}
Now in order to make a class able to spawn coroutines in it’s own tree of jobs for easier cancellation I can just delegate the interface to the implementation in a single line like this:
class ExampleAfter : CoroutineScopeAndJob by JobBasedScope(Dispatchers.IO)
Works like a charm, so I thought I’ll share it here for anyone else migrating.
Oh I also made a git gist of it all: