Cancellation Propagation in Coroutine Hierarchies
Understand how cancellation flows through parent-child coroutine relationships.
Parent-Child Relationship
When a coroutine launches another with launch, the child joins the parent's Job. Cancelling the parent cancels all children.
import kotlinx.coroutines.*
fun main() = runBlocking {
val parent = launch {
launch { delay(1000); println("child 1") }
launch { delay(1000); println("child 2") }
delay(1000)
println("parent")
}
delay(50)
parent.cancel()
parent.join()
println("All cancelled")
}Child Failure Cancels Parent
If a child throws a non-cancellation exception, it cancels the parent and all siblings — this is the default Job behavior.
import kotlinx.coroutines.*
fun main() = runBlocking {
try {
coroutineScope {
launch {
delay(50)
throw RuntimeException("child failed")
}
launch {
delay(1000)
println("sibling — never prints")
}
}
} catch (e: RuntimeException) {
println("Caught: ${e.message}")
}
}All lessons in this course
- Cooperative Cancellation: isActive and ensureActive
- withTimeout and withTimeoutOrNull
- Cleanup with finally and NonCancellable
- Cancellation Propagation in Coroutine Hierarchies