Programming Kotlin: Difference between SupervisorJob() and supervisorScope (324, 325)

Hi @venkats,

It has been mentioned in the description of ‘Supervisory Job’ title that 2 things as mentioned below result in the same effect - preventing the parent from cancelling when an unhandled exception occurs in one of the children

  1. Passing a SupervisorJob instance to the coroutine
  2. Wrapping the children inside a supervisorScope,

However, the example provided in ‘async/cancellationbidirectional.kts’ does use ‘SupervisorJob()’ in the parent ‘launch’, and parent job fails as mentioned in the book. When I try it, the result is the same: parent job fails, there is no successful 200 response, CancellationException is caught.

Why is that SupervisorJob() instance passage to the coroutine does not result in the desired behaviour? Using supervisorScope() works as expected. Is there any difference in using SupervisorJob() and supervisorScope()?

Please advise.

Thanks,
Harry

Hi @HarryDeveloper,

Thank you for the query.

The supervisorScope is a syntax sugar or a convenience function for creating a SupervisorJob. If the child coroutines run in a different SupervisorJob than the parent, then the cancellation of a Chile does not propagate to the parent.

It is much better to use supervisorScope than to use SupervisorJob, but from the curiosity point of view, you may try to create a SupervisorJob, something like this:

val job = launch(Dispatchers.IO + SupervisorJob() + handler) {

val supervisor = SupervisorJob()

launch(coroutineContext + supervisor) { fetchResponse(200, 5000) }
launch(coroutineContext + supervisor) { fetchResponse(200, 1000) }
launch(coroutineContext + supervisor) { fetchResponse(200, 3000) }

supervisor.children.forEach { it. join() }

/*
supervisorScope {
  launch { fetchResponse(200, 5000) }
  launch { fetchResponse(200, 1000) }
  launch { fetchResponse(200, 3000) }
}
*/

}

job.join()

Hope that answers your question.

Regards,

Venkat

Hi sir,

Thanks for your explanation.

So I see that by using supervisorScope, we are essentially creating a separate scope for the children, and that should stop the error from children propagating to the parent.

In that case, is there any specific reason we used SupervisorJob() in the launch() in the examples prior to the supervision topic? So those other examples should work even without SupervisorJob(). Is this right?

Thanks,
Harry