2017-01-16 17 views
2

Моя практика в этой ситуации является использование .sequence превратить F[G[A]] в G[F[A]]. Затем используйте Await.result(future_of_a_list, time_out), чтобы получить результаты. Однако может быть одна задача, которая требует много времени и времени. В этом случае я все еще хочу получить остальные результаты (при одновременном выполнении всех задач). Является ли это возможным? Как это сделать?Scala: Как собрать результат списка фьючерсов, когда некоторые из них тайм-аут?

Благодаря

+0

Я думаю, что это может помочь: http://stackoverflow.com/questions/20874186/scala-listfuture-to-futurelist-disregarding-failed- фьючерсы –

+0

@ MarkoŠvaljek Спасибо за комментарий. Но я не думаю, что это проблема. Исключение TimeOut не выбрано будущим исполнением. Вы либо блокируете каждое будущее (последовательное выполнение?), Либо блокируете в будущем списке (TimeOut происходит за пределами будущего). – huoenter

+0

@ MarkoŠvaljek Я уже поднял задачи, чтобы попробовать [_]. – huoenter

ответ

1

Ну, вы можете обернуть каждый Await в другом Future:

import scala.concurrent.{Await, Future} 
import scala.concurrent.ExecutionContext.Implicits.global 
import scala.concurrent.duration._ 
import scala.util.Success 

scala> val s = Seq(Future(1), Future(2), Future { Thread.sleep(2000); 3 }) 
s: Seq[scala.concurrent.Future[Int]] = List(Future(Success(1)), Future(Success(2)), Future(<not completed>)) 

scala> val fs = Future.traverse(s)(f => 
     Future(Await.result(f, 1 second)).transform(Success(_))) 
fs: scala.concurrent.Future[Seq[scala.util.Try[Int]]] = Future(<not completed>) 

scala> Await.result(fs, Duration.Inf) 
res2: Seq[scala.util.Try[Int]] = List(Success(1), Success(2), Failure(java.util.concurrent.TimeoutException: Futures timed out after [1 second])) 
0

Я согласен с идеей @Kolmar «s. Просто transform() в своем решении является новой версией Scala 2.12.x, а в версии 2.11.x - другой. Я попытался обновиться, но столкнулся с проблемами зависимостей. Я нашел свой путь, используя 2.11.x's fallbackTo. Так как мой Await.result(f, 1 second)) возвратит scalaz.Validation[Throwable, T], он также работает таким образом:

val fs = Future.traverse(s)(f => 
    Future(Await.result(f, 1 second)).fallbackTo(Future(Failure(new TimeoutException())))