2015-04-20 42 views
1

我試圖等待函數完成或5秒後超時,但無論我做什麼,我都無法防止以下異常。有趣的是它是由父演員抓到:等待函數完成或5秒後在Akka中超時

java.util.concurrent.TimeoutException: Futures timed out after [5 seconds] 

一說我想(從this問題)的解決方案:

val f = Future { dockerClient.execStartCmd(execCreateCmdResponse.getId()).exec() } 
val result: Try[InputStream] = Await.ready(f, 5.seconds).value.get 

val resultEither = result match { 
    case Success(t) => log.info("right") 
    case Failure(e) => log.info("left") 
} 
+2

你見過所有其他的選擇嗎? '等待'是阻止和邪惡... http://semberal.github.io/scala-future-timeout-patterns.html –

+0

@AndreyTyukin謝謝你的文章。我使用ask模式解決了它。 – Josef

+0

這種「答案」通常會做什麼?關閉這個問題,以便沒有人能夠利用semberal的知識? –

回答

3

事實上它可能與阿卡問模式來實現這一點。但是有一種不同的解決方案可以在沒有阿卡的情況下使用。

包裝你阻擋Await代碼到另一個Future並註冊onComplete功能

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

val sleepTimeout = 1*1000 

val f = Future(Thread.sleep(sleepTimeout); Try(10)) 
val timeoutFuture = Future(Await.result(f, 5.seconds)) 
timeoutFuture.onComplete { 
    case Success(Success(t)) => println(t) 
    case Success(Failure(ex)) => println("error on Try" + ex.getMessage) 
    case Failure(e) => println("timeout " + e.getMessage) 
} 

解釋比賽的情況下

  • Success(Success(t))首先Success對於timeoutFuture,這意味着它沒有超時。第二SuccessTry - 意思是沒有例外拋出。
  • Success(Failure(ex))與第一個相同,但在Try之內有例外
  • Failure(e)這是處理超時的地方。
+0

我不建議你在'Future'內等待,因爲你用這種方式阻止2個線程。您需要使用調度程序實現超時。看看這個:http://nami.me/2015/01/20/scala-futures-with-timeout/ –