Boolean ops aren't as clever as they could be
johanandren opened this issue · 1 comments
johanandren commented
Consider these cases:
Future { Thread.sleep(5000); false } && Future.successful(false)
Future { Thread.sleep(5000); false } || Future.successful(true)
We could make them resolve as fast as the fastest future, in best case.
johanandren commented
The problem is that a solution that tries to short circuit becomes a bit race conditiony and how failures are propagated becomes unclear.
Sample solution, if there is a failure in both fa
and fb
, which is used?
/**
* @return A new future that will complete with false as soon as either future completes with false
* or true when both futures has completed and are true.
*/
def firstAnd(fa: Future[Boolean], fb: Future[Boolean])(implicit ec: ExecutionContext) = {
val promise = Promise[Boolean]()
fa.onComplete {
case Success(false) => promise.trySuccess(false)
case Failure(ex) => promise.tryFailure(ex)
}
fb.onComplete {
case Success(false) => promise.trySuccess(false)
case Failure(ex) => promise.tryFailure(ex)
}
fa.zip(fb).onComplete {
// this is the only case that can happen after the above
case Success((true, true)) => promise.trySuccess(true)
}
promise.future
}