Skip to content

Job‐Hierarchy

Devrath edited this page Jan 15, 2024 · 6 revisions

UseCase-1:Consider the relationship as described

Untitled Diagram drawio

Observation

  • 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 🚨 🚨

Output

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

Code

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()
    }

}
Clone this wiki locally