So far, we've seen examples of coroutines being launched at the top level—using either GlobalScope or runBlocking , and we've seen examples of nested coroutines creating a parent-child relationship. When writing larger programs, it is common that parent and child tasks have a shared life cycle.
For example, a web server may service a request to update a user account—change the password, email the user that their password has been changed, and terminate any existing sessions so the user must reauthenticate with the new password.
Each of these tasks may happen concurrently, or they may happen sequentially. Either way, it would be useful to tie them together as a group of related tasks, where overall success depends on the success of each part.
As we saw earlier, coroutines can be nested into parent-child hierarchies. There are three...