Launching coroutines from a suspended function

Every suspendable function has access to the global variable coroutineContext which you can trivially wrap in CoroutineScope, but that is not its intended purpose. It's there so you can check at any point whether your coroutine was cancelled, reach the debug info like the job name, etc.

In the words of Roman Elizarov in his recent Medium post:

suspend fun doNotDoThis() {
    CoroutineScope(coroutineContext).launch {
        println("I'm confused")
    }
}

Do not do this!

A suspendable function should not fire off concurrent work that may go on after it returns. It should only use concurrency to achieve parallel decomposition of a task, and that means it will wait for all the child coroutines to complete.

You should decide to either use a plain function that is the receiver of CoroutineScope (signaling the intention to launch concurrent work) or use a suspendable function that awaits on the completion of all the work it initiated.

So, if you want parallel decomposition, then use a coroutineScope or, possibly a supervisorScope block:

coroutineScope {
    launch { 
        // ... task to run in the background
    }
    // ... more work while the launched task runs in parallel
}
// All work done by the time we reach this line

coroutineScope is a suspendable function and it won't complete until all the coroutines it launched complete.