简体   繁体   中英

Scala: what is the right way to fold a collection of futures?

I have a piece of code that sends broadcast message to a set of actors and collects their responses. Please look at the simplified code:

{
  val responses: Set[Future[T] = // ask a set of actors
  val zeroResult: T
  val foldResults: (T, T) => T

  //1. Future.fold(responses)(zeroResult)(foldResults)
  //2. (future(zeroResult) /: responses) { (acc, f) => for { x <- f; xs <- acc } yield foldResults(x, xs) }
} foreach {
   client ! resp(_)
}

Then I noticed that behaviors of lines of code 1 and 2 differ. Eg there are 4 actors sending Traversable(1) as response, and

zeroResult = Traversable.empty[Int]
foldResults = { _ ++ _ }

The results of the first line are different: usually I get List(1, 1, 1, 1), but sometimes List(1, 1, 1) or even List(1, 1). It wasn't surprising for me, because Future.fold is unblocking, so it seems some responses could be missed.

But the second line always yields List of four ones.

Could anyone explain the reason why these kinds of fold differ and which of them is preferable?

The surprising thing for me in your question is the fact that your first fold (which I find preferable by reason of its conciseness) sometimes seems to operate on a list of three (or two) successfully completed futures.

In the normal scheme of things, you have 3 possible outcomes for a future:

  1. Completed normally
  2. Failed (completed with exception)
  3. Uncompleted

Both of the folds that you give will yield a single future that is uncompleted while all of its component futures are completed, or failed if any future (or the fold operation) fails, or completed if all goes well. (Your sentence Future.fold is unblocking, so it seems some responses could be missed is incorrect.)

I can only think that you have some other code somewhere that is completing futures with no result if a certain timeout is breached.

Apart from that, you have swapped the order of the operands in the fold operation in line 2 (should be yield foldResults(xs, x) ) so the final order is reversed with respect to line 1.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM