Last active
October 22, 2015 23:31
-
-
Save kermitas/c102d361204978ea66a1 to your computer and use it in GitHub Desktop.
Future.sequence() is fine but it will fail if any of passed Futures will fail. Sometimes we would like to have the same functionality but it should not fail - it should just have a collection of completed Futures (completed with Success or Failure).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package scala.concurrent | |
import scala.util.{ Try, Success } | |
object FutureUtils { | |
/** | |
* @return resulted future will be completed when all passed futures will be completed (either with Success or Future) | |
*/ | |
def completeAll[T](fs: Future[T]*)(implicit ec: ExecutionContext): Future[Seq[Future[T]]] = Future.successful(fs).flatMap { fs => | |
if (fs.isEmpty) { | |
Future.successful(fs) | |
} else { | |
import java.util.concurrent.atomic.AtomicInteger | |
val remaining = new AtomicInteger(fs.length) | |
val p = Promise[Seq[Future[T]]]() | |
fs.foreach { | |
_ onComplete { | |
case _ => if (remaining.decrementAndGet == 0) p.complete(Success(fs)) | |
} | |
} | |
p.future | |
} | |
} | |
/** | |
* Converts passed futures to tries. | |
* | |
* @param fs all passed futures should be completed | |
*/ | |
def futureToTry[T](fs: Future[T]*)(implicit ec: ExecutionContext): Seq[Try[T]] = fs.map(_.value).map { | |
_ match { | |
case Some(r) => r | |
case None => throw new Exception("All passed futures should be completed before calling this method.") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment