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. E.g. 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?