【问题标题】:Scala: How to gather the result of a list of futures when some of them time out?Scala:当其中一些超时时如何收集期货列表的结果?
【发布时间】:2017-05-31 20:36:43
【问题描述】:

在这种情况下,我的做法是使用.sequence 将F[G[A]] 转换为G[F[A]]。然后使用Await.result(future_of_a_list, time_out) 得到结果。但是,可能有一项任务需要很长时间并且超时。在这种情况下,我仍然想获得其余的结果(同时并行运行所有任务)。可能吗?怎么做?

谢谢

【问题讨论】:

  • 我认为这可能会有所帮助:stackoverflow.com/questions/20874186/…
  • @MarkoŠvaljek 感谢您的评论。但我不认为这是问题所在。 Future 执行不会引发 TimeOut 异常。您要么阻止每个未来(顺序执行?),要么阻止未来列表(超时发生在未来之外)。
  • @MarkoŠvaljek 我已经将任务交给 Try[_]。

标签: scala future scalaz


【解决方案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]))

【讨论】:

    【解决方案2】:

    我同意@Kolmar 的想法。只是他的解决方案中的 transform() 是新的 Scala 2.12.x 版本,而在 2.11.x 中它具有不同的签名。我尝试升级但遇到了依赖问题。我找到了使用 2.11.x 的 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())))
    

    【讨论】:

      猜你喜欢
      • 2018-08-22
      • 2021-09-21
      • 2023-03-03
      • 2021-06-17
      • 2019-09-01
      • 1970-01-01
      • 2021-03-02
      • 2014-12-30
      • 2013-11-29
      相关资源
      最近更新 更多