Skip to content

Instantly share code, notes, and snippets.

@nineclue
Last active August 29, 2015 14:23
Show Gist options
  • Select an option

  • Save nineclue/8ae82583da87e3be6049 to your computer and use it in GitHub Desktop.

Select an option

Save nineclue/8ae82583da87e3be6049 to your computer and use it in GitHub Desktop.
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