Last active
August 29, 2015 14:23
-
-
Save nineclue/8ae82583da87e3be6049 to your computer and use it in GitHub Desktop.
Demo of wrapping future with Try, as stackoverflow(http://stackoverflow.com/questions/20874186/scala-listfuture-to-futurelist-disregarding-failed-futures)
This file contains hidden or 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
| import concurrent.{Future, Promise} | |
| import scala.concurrent.ExecutionContext.Implicits.global | |
| import util.{Random, Try, Success, Failure} | |
| object App { | |
| def main(as:Array[String]) = test | |
| def test = { | |
| // returns future of random Int, with 30% failure rate | |
| def randomFutureWithFailures:Future[Int] = { | |
| val p = Promise[Int] | |
| Future { | |
| Thread.sleep(Random.nextInt(1000)) | |
| if (Random.nextDouble < 0.3) | |
| p.failure(new Throwable("something wrong happened")) | |
| else | |
| p.success(Random.nextInt(10)) | |
| } | |
| p.future | |
| } | |
| // wraps successful future with Success and failure with Failure | |
| def future2FutureTry[T](f:Future[T]):Future[Try[T]] = | |
| f.map(Success(_)).recover({ case f => Failure(f) }) | |
| val start = System.currentTimeMillis | |
| val swatch = Array.fill(10)(0L) | |
| val fs = (1 to 10).map(_ => randomFutureWithFailures) | |
| fs.zipWithIndex.foreach({ | |
| case (f, i) => | |
| f.onComplete { | |
| // record future's finish time | |
| case _ => swatch(i) = System.currentTimeMillis | |
| } | |
| }) | |
| // wait enough time for all future to finish | |
| Thread.sleep(2000) | |
| assert(fs.forall(_.isCompleted)) | |
| // wraps future with Try, AFTER all futures became reality! | |
| val fts:Seq[Future[Try[Int]]] = fs.map(future2FutureTry) | |
| // convert sequence of futures to future of sequence | |
| val fss:Future[Seq[Try[Int]]] = Future.sequence(fts) | |
| fss.onComplete { | |
| case Success(ts) => | |
| ts.zipWithIndex.foreach({ | |
| case (t, i) => | |
| t match { | |
| case Success(f) => | |
| println(s"$i : ${(swatch(i)-start)/1000.0}s : Success($f)") | |
| case Failure(f) => | |
| println(s"$i : ${(swatch(i)-start)/1000.0}s : Failure($f)") | |
| } | |
| }) | |
| case Failure(_) => // just ignore, not possible ? | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment