Task Design #

Parallel tasks #

For simple tasks that we want to run in parallel and then wait for them all to finish before exiting, we recommend using standard Kotlin procedures.

Wrap launches in a coroutineScope, and Kotlin ensures that every launch is complete before exiting the scope.

Example

In this example, the coroutineScope block doesn’t exit until both coroutines launched inside are complete.

suspend fun foo() {
    coroutineScope {
        launch {
            this.doSomething()
        }
        launch {
            this.doSomethingElse()
        }
    }
    println("done")
}

Task response #

For situations where we need results of the tasks we spin off, such as waiting for responses to requests, we recommend using async blocks inside a coroutineScope.

This is similar to the previous example with launch, but with async, it allows us to get the responses of calls.

Example

In this example, bar() makes one coroutine for each element in requests and then runs them in parallel. Then we call `awaitAll() to get all the responses from the requests. Because requests are run in parallel, this is more efficient than running them one at a time.

suspend fun bar(requests: List<Request>) {
    val asyncRequests = coroutineScope {
        requests.map {
            async {
                makeRequest(it)
            }
        }
    }
    val responses = asyncRequests.awaitAll()
}