UseCase-1:Consider the relationship as described
We have all co-routines launched in the same scope
Note that grand-Parent, parent-1, and parent-2 launched and completed, They did not wait for the left co-routines to complete.
When we click cancel, exception is caught, and then invokeOnCompletion is triggered.
Also the exception occurs inside the scope and not outside.
🚨🚨 Also I observed when you use launch, You cannot make the parents wait for the children to complete. If that behaviour is needed, We need to use async and await 🚨 🚨
GrandParent invokeOnCompletion triggered
Parent - 2 invokeOnCompletion triggered
Parent - 1 - child- 1 ------------------ > 0
Parent - 1 - child- 2 ------------------ > 0
Parent - 1 invokeOnCompletion triggered
Parent - 2 - child- 2 ------------------ > 0
Parent - 2 - child- 1 ------------------ > 0
Parent - 1 - child- 1 ------------------ > 1
Parent - 1 - child- 2 ------------------ > 1
Parent - 2 - child- 2 ------------------ > 1
Parent - 2 - child- 1 ------------------ > 1
Parent - 1 - child- 1 ------------------ > 2
Parent - 1 - child- 2 ------------------ > 2
Parent - 2 - child- 2 ------------------ > 2
Parent - 2 - child- 1 ------------------ > 2
< ------------------ User presses cancel ------------------ >
Exception caught inside Parent - 1 - child- 1 scope
Parent - 1 - child- 1 invokeOnCompletion triggered
Exception caught inside Parent - 2 - child- 1 scope
Parent - 2 - child- 1 invokeOnCompletion triggered
Exception caught inside Parent - 2 - child- 2 scope
Parent - 2 - child- 2 invokeOnCompletion triggered
Exception caught inside Parent - 1 - child- 2 scope
Parent - 1 - child- 2 invokeOnCompletion triggered
class JobDemoSelectionVm @Inject constructor( ) : ViewModel() {
private val scopeJob = Job ()
private val ourScope = CoroutineScope (scopeJob + Dispatchers .Default )
fun demo () {
try {
ourScope.launch(CoroutineName (" GrandParent" )) {
try {
parent1Block()
parent2Block()
}catch (ex: Exception ){
println (" Exception caught inside GrandParent scope" )
}
}.invokeOnCompletion {
println (" GrandParent invokeOnCompletion triggered" )
}
}catch (ex: Exception ){
println (" Exception caught outside GrandParent scope" )
}
}
private fun parent1Block (){
try {
ourScope.launch(CoroutineName (" Parent-1" )) {
try {
parent1Child1Block()
parent1Child2Block()
}catch (ex: Exception ){
println (" Exception caught inside Parent-1 scope" )
}
}.invokeOnCompletion {
println (" Parent-1 invokeOnCompletion triggered" )
}
}catch (ex: Exception ){
println (" Exception caught outside Parent-1 scope" )
}
}
private fun parent2Block (){
try {
ourScope.launch(CoroutineName (" Parent-2" )) {
try {
parent2Child1Block()
parent2Child2Block()
}catch (ex: Exception ){
println (" Exception caught inside Parent-2 scope" )
}
}.invokeOnCompletion {
println (" Parent-2 invokeOnCompletion triggered" )
}
}catch (ex: Exception ){
println (" Exception caught outside Parent-2 scope" )
}
}
private fun parent1Child1Block (){
try {
ourScope.launch(CoroutineName (" Parent-1-child-1" )) {
try {
repeat(10 ){
println (" Parent-1-child-1 ------------------>$it " )
delay(1000 )
}
}catch (ex: Exception ){
println (" Exception caught inside Parent-1-child-1 scope" )
}
}.invokeOnCompletion {
println (" Parent-1-child-1 invokeOnCompletion triggered" )
}
}catch (ex: Exception ){
println (" Exception caught outside Parent-1-child-1 scope" )
}
}
private fun parent1Child2Block (){
try {
ourScope.launch(CoroutineName (" Parent-1-child-2" )) {
try {
repeat(10 ){
println (" Parent-1-child-2 ------------------>$it " )
delay(1000 )
}
}catch (ex: Exception ){
println (" Exception caught inside Parent-1-child-2 scope" )
}
}.invokeOnCompletion {
println (" Parent-1-child-2 invokeOnCompletion triggered" )
}
}catch (ex: Exception ){
println (" Exception caught outside Parent-1-child-2 scope" )
}
}
private fun parent2Child1Block (){
try {
ourScope.launch(CoroutineName (" Parent-2-child-1" )) {
try {
repeat(10 ){
println (" Parent-2-child-1 ------------------>$it " )
delay(1000 )
}
}catch (ex: Exception ){
println (" Exception caught inside Parent-2-child-1 scope" )
}
}.invokeOnCompletion {
println (" Parent-2-child-1 invokeOnCompletion triggered" )
}
}catch (ex: Exception ){
println (" Exception caught outside Parent-2-child-1 scope" )
}
}
private fun parent2Child2Block (){
try {
ourScope.launch(CoroutineName (" Parent-2-child-2" )) {
try {
repeat(10 ){
println (" Parent-2-child-2 ------------------>$it " )
delay(1000 )
}
}catch (ex: Exception ){
println (" Exception caught inside Parent-2-child-2 scope" )
}
}.invokeOnCompletion {
println (" Parent-2-child-2 invokeOnCompletion triggered" )
}
}catch (ex: Exception ){
println (" Exception caught outside Parent-2-child-2 scope" )
}
}
fun rootCancel () {
scopeJob?.cancel()
}
}