Scala - 等待所有期货在一段时间内完成

时间:2015-10-19 21:27:52

标签: scala future

我有List[Future[String]]并希望等待一段时间,以便收集成功的计算以及在特定时间段内未完成的期货的重新运行。

在伪代码中,它看起来像:

val inputData: List[String] = getInputData()
val futures : List[Future[String]] = inputData.map(toLongRunningIOOperation)
val (completedFutures, unfinishedFutures) = Await.ready(futures, 2 seconds)
val rerunedOperations : List[Future[String]] = unfinisedFutures.map(rerun)

如果您需要对通常延迟为(低p99 <60ms)的外部服务执行多次调用,但有时请求处理时间超过5秒(因为当前状态/负载),此解决方案可能很有用。在这种情况下,最好重新运行这些请求(即另一个服务实例)。

1 个答案:

答案 0 :(得分:0)

例如,使用Future.firstCompletedOf函数来获取未来的时间

def futureToFutureOption[T](f: Future[T]): Future[Option[T]] = f.map(Some(_)).recover[Option[T]]{case _ => None}
val inputData: List[String] = List("a", "b", "c", "d")
val completedFuture = inputData.map { a =>
  a match {
    case "a" | "c" => Future.firstCompletedOf(Seq(Future{Thread.sleep(3000); a},
      Future.failed{Thread.sleep(2000); new RuntimeException()}))
    case _ => Future(a)
  }
}

val unfinished = Future.sequence(completedFuture.map(futureToFutureOption)).map(list => inputData.toSet -- list.flatten.toSet)

val rerunedOperations: Future[Set[Future[String]]] = unfinished.map { _.map(foo) }

def foo(s: String): Future[String] = ???

示例rerunedOperations中的示例与您的示例中的类型不同,但我认为这对您来说没问题。 还要记住,如果你在未来对某个外部系统进行一些调用,并且未来没有在适当的时间内完成,这种方法不会阻止未完成的未来执行,我的意思是实际调用外部系统将在您尝试拨打另一个电话时进行处理