Skip to content

Instantly share code, notes, and snippets.

@RayRoestenburg
Last active May 20, 2021 21:45
Show Gist options
  • Save RayRoestenburg/6096365 to your computer and use it in GitHub Desktop.
Save RayRoestenburg/6096365 to your computer and use it in GitHub Desktop.
firstSucceededOf, returns a future containing the first successful result or contains the last failure if all futures have failed. What's wrong with it?
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util._
import java.util.concurrent.atomic.AtomicInteger
def firstSucceededOf[T](futures: TraversableOnce[Future[T]])(implicit executor: ExecutionContext): Future[T] = {
val p = Promise[T]()
val size = futures.size
val failureCount = new AtomicInteger(0)
futures foreach { _.onComplete{
case Success(v) => p.trySuccess(v)
case Failure(e) =>
val count = failureCount.incrementAndGet
if(count == size) p.tryFailure(e)
}
}
p.future
}
@jrudolph
Copy link

There's a bug in there: volatile isn't safe for atomic increments (use AtomicInteger).

@RayRoestenburg
Copy link
Author

Thanks Johannes! fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment