I have a task runner as follows
package taskman
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
final class Task private (
desc: String,
dependencies: Seq[Task] = Seq.empty[Task],
body: => Unit
) {
def run(): Future[Unit] = Future {
// println(s"Executing dependencies for $desc")
Future
.sequence(dependencies.map(_.run()))
.map { _ => body }
}
}
object Task {
def task(desc: String, dependencies: Seq[Task] = List.empty[Task])(
body: => Unit
): Task =
new Task(desc, dependencies, body)
}
object taskTest extends App {
import Task._
val boilWater = task("Boil water") {
println("Boiling water ")
}
val boilMilk = task("Boil milk") {
println("Boiling milk")
}
val mixWaterAndMilk =
task("Mix milk and water", Seq(boilWater, boilMilk)) {
println("Mixing milk and water")
}
val addCoffeePowder = task("Add coffee powder", Seq(mixWaterAndMilk)) {
println("Adding coffee powder")
}
val addSugar = task("Add sugar", Seq(addCoffeePowder)) {
println("Adding sugar")
}
val makeCoffee = task("Make coffee", Seq(addSugar)) {
println("Coffee is ready to serve")
}
Await.result(makeCoffee.run, 10.seconds)
}
I expect the dependencies to run in parallel and after finishing then execute the body. But I am always getting this in the wrong order.
The expected order is as follows
Boiling water Boiling milk Mixing milk and water Adding coffee powder Adding sugar Coffee is ready to serve
Boiling milk and water can be done in any order but the rest of the things should be executed in order. I am executing the body on Future.sequence.map {}, but still the order isn't correct. There is something wrong with this code for sure but I am not able to figgure it out.
The problem is the spurious extra Future
in run
.
def run(): Future[Unit] = Future { // <-- Not required
Future
.sequence(dependencies.map(_.run()))
.map { _ => body }
}
Removing it fixes the problem:
def run(): Future[Unit] =
Future
.sequence(dependencies.map(_.run()))
.map { _ => body }