Tom Everton
04/13/2022, 11:38 AMclass Outer : Closeable {
private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
private var inner: Inner? = null
fun startInner() {
inner = Inner(InnerRepo(), InnerApi())
}
fun stopInner() {
inner.close()
inner = null
}
override fun close() {
scope.cancel()
}
... // More code that uses the outer scope
}
And in the inner I have some code that calls suspend functions:
class Inner(
private val repo: InnerRepo,
private val api: InnerApi
) : Closeable {
private val innerScope = CoroutineScope(<http://Dispatchers.IO|Dispatchers.IO> + SupervisorJob())
fun sendData() {
innerScope.launch {
api.sendData(repo.getData())
}
}
override fun close() {
innerScope.cancel()
}
}
Is there a way to link the innerScope
to the outerScope
as it makes sense that the innerScope
would always want to be cancelled if the outer scope cancels, or is that even something that should be done? Also, if the pattern above is completely wrong let me know!
CheersSam
04/13/2022, 12:07 PMstartInner
you call scope.launch { ... }
, something like this:
fun startInnner() {
innerJob = scope.launch { Inner(this, InnerRepo(), InnerApi()) }
}
Where I added this
as the first argument to Inner
, that would be a reference to the CoroutineScope
created by launch
, so that Inner
wouldn't need to create its own scope.ephemient
04/13/2022, 12:12 PMinnerJob = Job(outerScope.coroutineContext.job)
Tom Everton
04/13/2022, 12:41 PMSam
04/13/2022, 1:35 PMlaunch
is the straightforward way to achieve structured concurrency, where one job/scope is a child of another. Capturing that inner scope in an object is probably not uncommon if your code is more object-oriented and the work done by the child job is non-trivial.Tom Everton
04/13/2022, 1:42 PM