我在游戏框架的scala中使用FUTURE。但是在合并多个期货时超时的情况下,我很难获得部分最终结果。这是我的代码的作用。它有两个未来分别查询两个提供程序。然后使用 for/yield 语句合并结果。然后等待具有超时值的结果。当两个提供程序按时回复查询时,它工作正常。但是,如果只有一个提供程序按时回复,我知道 await 将超时,但在这种情况下,我仍然需要检索从按时回复的另一个提供程序返回的数据。我该怎么做?
val pool = Executors.newCachedThreadPool()
implicit val ec = ExecutionContext.fromExecutorService(pool)
var future1 = Future(QueryProvider(provider1, request1))
var future2 = Future(QueryProvider(provider2, request2))
val future = for {
result1 <- future1
result2 <- future2
} yield (Merge(result1, result2))
val duration = Duration(60000, MILLISECONDS)
try{
result = Await.result(future, duration).asInstanceOf[string]
}
catch{
case _: Exception => println("time out...")
//Here how can I retrieve provider1's result if only provider2 timeout???***
}
akka
中的after
而不是阻止Await.result
:
val timeout =
akka.pattern.after(FiniteDuration(60000, MILLISECONDS), using = system.scheduler){
Future.successful(None)
}
val resFuture = for {
result1 <- Future firstCompletedOf Seq(future1.map{Some(_)}, timeout)
result2 <- Future firstCompletedOf Seq(future2.map{Some(_)}, timeout)
} yield (result1, result2)
val result = resFuture map {
case (Some(r1), Some(r2)) => Merge(r1, r2)
case (Some(r1), None) => PartialResult1(r1)
case (None, Some(r2)) => PartialResult2(r2)
case _ => EmptyResult
}
在这种情况下resFuture
将在 60 秒内完成,您可以处理部分结果。此外,您不需要Play
Await
- 您可以使用Async
.
如果你有许多相同类型的等价期货,你可以像这样使用它:
val futures: Seq[Future[Int]] = ???
val futureWithTimeout =
futures.map{ f => Future firstCompletedOf Seq(f.map{Some(_)}, timeout) }
val result: Future[Seq[Option[Int]]] = Future.sequence(futureWithTimeout)
// In case you need to know index of completed or not completed future
val indexedResults = result.zipWithIndex
// In case you just need only completed results
val completedResults: Future[Seq[Option[Int]]] = result.map{_.flatten}
此处的类型仅用于说明。