2015-10-19 82 views
0

我有List[Future[String]],我想等待一段時間,以便收集成功的計算以及重新運行在指定時間段內未完成的期貨的操作。斯卡拉 - 等待所有期貨在期限內完成

在僞代碼將是這樣的:如果你需要執行多次調用外部服務時,其通常的等待時間(低P99 <爲60ms),但有時請求進行處理

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) 

這樣的解決方案可能是有用的多超過5秒(由於當前狀態/負載)。在這種情況下,最好重新運行這些請求(即服務的另一個實例)。

+0

可能的解決方案[此處](http://stackoverflow.com/questions/16304471/scala-futures-built-in-timeout) –

回答

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中有不同的類型,在你的例子,但我認爲這將是對你罰款。 另外請記住,如果您正在對未來內部的外部系統進行一些調用,並且未來未在適當的時間內完成,則此類方法不會阻止未來執行的未完成,我的意思是實際調用外部系統將正在處理,而您將嘗試撥打另一個電話