Reputation: 16935
I'm trying to run a series of dumb Scala Future
s in parallel. I have the following code, which I expect to take ~10 seconds:
import scala.concurrent.Future
import scala.util.{Success, Failure}
import scala.concurrent.ExecutionContext.Implicits.global
def scalaFoo = Future {
Thread.sleep(10*1000) // sleep for 10 seconds
List(1,2,3)
}
def scalaBar = Future {
Thread.sleep(10*1000)
List(4,5,6)
}
def scalaBaz = Future {
Thread.sleep(10*1000)
List(7,8,9)
}
val flatRes: Future[List[Int]] = for {
scalaFooRes <- scalaFoo
scalaBarRes <- scalaBar
scalaBazRes <- scalaBaz
} yield (scalaFooRes ++ scalaBarRes ++ scalaBazRes)
flatRes onComplete {
case Success(li) => println(li.foldLeft(0)(_ + _))
case Failure(e) => println(e.getMessage)
}
But what I find is that the onComplete
takes ~30 seconds, so my jobs are running sequentially.
How can I make them run in parallel? Why aren't they running in parallel now?
Upvotes: 3
Views: 5317
Reputation: 101
You also could use Future.sequence:
def scalaFoo = Future {
Thread.sleep(3*1000) // sleep for 10 seconds
List(1,2,3)
}
def scalaBar = Future {
Thread.sleep(3*1000)
List(4,5,6)
}
def scalaBaz = Future {
Thread.sleep(3*1000)
List(7,8,9)
}
Future.sequence(List(scalaFoo, scalaBar, scalaBaz)).onComplete({
case Success(li) => println(li.flatten.sum)
case Failure(e) => println(e.getMessage)
})
Upvotes: 7
Reputation: 8866
You can run these futures in parallel declaring variables first:
val foo = scalaFoo
val bar = scalaBar
val baz = scalaBaz
And then doing for:
for {
scalaFooRes <- foo
scalaBarRes <- bar
scalaBazRes <- baz
} ...
Upvotes: 3
Reputation: 1544
You need to create them before the for expression, otherwise they wont run in parallel. If you change the methods to vals, it should work.
Upvotes: 11