Kotlin Project Task Runner
The task runner project builds a small plan of named tasks and runs it. Async work reports results in plan order, and a flow reports the task names as a progress list.
Building a plan of tasks
The builder collects two tasks inside its receiver lambda. Each result comes from the plain score function, and the loop prints the plan.
data class Task(val name: String, val result: Int)
class TaskPlan {
val tasks = mutableListOf<Task>()
fun task(name: String, result: Int) {
tasks.add(Task(name, result))
}
}
fun buildPlan(init: TaskPlan.() -> Unit): TaskPlan {
val plan = TaskPlan()
plan.init()
return plan
}
fun score(base: Int): Int {
return base * 10
}
fun main() {
val built = buildPlan {
task("Clean", score(2))
task("Sort", score(3))
}
for (task in built.tasks) {
println(task.name + ": " + task.result)
}
}Results awaited in plan order
Each task result starts as async work. The loop awaits the deferred values in plan order, so the lines print in that same order.
import kotlinx.coroutines.*
data class Task(val name: String, val result: Int)
class TaskPlan {
val tasks = mutableListOf<Task>()
fun task(name: String, result: Int) {
tasks.add(Task(name, result))
}
}
fun buildPlan(init: TaskPlan.() -> Unit): TaskPlan {
val plan = TaskPlan()
plan.init()
return plan
}
fun score(base: Int): Int {
return base * 10
}
fun main() = runBlocking {
val built = buildPlan {
task("Clean", score(2))
task("Sort", score(3))
task("Pack", score(1))
}
val results = built.tasks.map { entry ->
async { entry.result }
}
for (index in built.tasks.indices) {
println(built.tasks[index].name + ": " + results[index].await())
}
}Task names as a progress flow
The flow emits the name of each task in plan order. collect prints each name as it arrives, so the list reads as a progress list.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
data class Task(val name: String, val result: Int)
class TaskPlan {
val tasks = mutableListOf<Task>()
fun task(name: String, result: Int) {
tasks.add(Task(name, result))
}
}
fun buildPlan(init: TaskPlan.() -> Unit): TaskPlan {
val plan = TaskPlan()
plan.init()
return plan
}
fun score(base: Int): Int {
return base * 10
}
fun taskNames(plan: TaskPlan): Flow<String> = flow {
for (task in plan.tasks) {
emit(task.name)
}
}
fun main() = runBlocking {
val built = buildPlan {
task("Clean", score(2))
task("Sort", score(3))
task("Pack", score(1))
}
taskNames(built).collect { name ->
println(name)
}
}Example
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
data class Task(val name: String, val result: Int)
class TaskPlan {
val tasks = mutableListOf<Task>()
fun task(name: String, result: Int) {
tasks.add(Task(name, result))
}
}
fun buildPlan(init: TaskPlan.() -> Unit): TaskPlan {
val plan = TaskPlan()
plan.init()
return plan
}
fun score(base: Int): Int {
return base * 10
}
fun taskNames(plan: TaskPlan): Flow<String> = flow {
for (task in plan.tasks) {
emit(task.name)
}
}
fun main() = runBlocking {
val built = buildPlan {
task("Clean", score(2))
task("Sort", score(3))
task("Pack", score(1))
}
val results = built.tasks.map { entry ->
async { entry.result }
}
for (index in built.tasks.indices) {
println(built.tasks[index].name + ": " + results[index].await())
}
println("Progress")
taskNames(built).collect { name ->
println(name)
}
}Key points
- A builder class collects tasks added inside a receiver lambda.
- Each task stores a name and an Int result from a plain function.
- runBlocking starts the run and waits for it to finish.
- async starts each task result as deferred work.
- Awaiting the deferred values in plan order prints results in that order.
- A flow emits the task names one at a time.
- collect receives each name in emission order.
In this example, the builder first describes three tasks with results from the score function. The loop awaits each deferred result in plan order and prints it, and the flow then emits the task names in that same order for the progress list.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Kotlin Playground
Exercise
Why do the results print in plan order in this project?