Another thing that troubles me - why `SupervisorJo...
# coroutines
m
Another thing that troubles me - why
SupervisorJob
is designed in this way, that it needs to be a part of scope, and does not work as a simple context passed as an argument?
Copy code
fun main(): Unit = runBlocking(SupervisorJob()) {
    launch {
        delay(100)
        throw Error()
    }
    launch {
        delay(200)
        print("Done")
    }
}
// Just Error
Copy code
fun main(): Unit = runBlocking {
    with(CoroutineScope(coroutineContext + SupervisorJob())) {
        launch {
            delay(100)
            throw Error()
        }
        val job = launch {
            delay(200)
            print("Done")
        }
        job.join()
    }
}
// Error...
// Done
e
Copy code
supervisorScope {
👍🏻 1
it's similar to
withContext(SupervisorJob())
but works to keep structured concurrency
note that what you have there has another danger: if you create a new coroutine scope and don't keep any references to it (or something in it) it may be garbage collected and stop running
m
I found the answer myself - the first case does not work, because those launches are child of a child of a
SupervisorJob
.
runBlocking
makes a child job, and
launch
also makes a child based on the
runBlocking
job.
SupervisorJob
gives a special behaviour only for its children, not children of its children.
This is error resilient:
Copy code
fun main(): Unit = runBlocking {
    val s = SupervisorJob()
    launch(s) {
        delay(100)
        throw Error()
    }
    launch(s) {
        delay(200)
        print("Done")
    }
    delay(300)
    s.complete()
    s.join()
}
// Error
// Done