2014-01-08 82 views
0

我在使用java的akka​​中使用主 - 從架構。主站接收表示他傳遞給從站的作業命令的消息。這些工作涉及到調用不是開源的第三方庫,有時只是掛起和阻止執行而不會拋出任何異常而崩潰。 Akka並不認爲這是失敗,並且不斷髮送消息給這個actor正在使用的郵箱,但是由於第一次調用會無限期地阻塞,郵箱中的其餘命令將永遠不會被執行。如何在akka超時後強制演員失敗

我的目標是用超時過期和異常模擬這種類型的故障,以便將整個事件轉發到akka中的故障策略構建。所以我的問題是,我可以以某種方式配置一個actor收到消息後拋出一個異常,並且在超時後它的執行沒有完成?

如果不是,那麼在沒有執行任何阻止操作的情況下處理這種情況有哪些其他方法?我正在考慮將執行封裝在未來中,並從一名將阻止未來超時的演員中調用它。它的工作原理,但正如許多人所暗示的那樣,封鎖並不是一個好的解決方案。

+0

在你的問題中涉及到我的一件事是你的第三方API只是掛起和阻塞。發生這種情況時,ExecutionContext中的線程也會基本上被阻塞。足夠發生這種情況,並且最終會削弱你的ExecutionContext,從而扼殺演員系統的其餘部分。如果您決定使用期貨,請確保它們使用來自您的參與者系統的單獨的'ExecutionContext',以便防止這個有問題的代碼。 – cmbaxter

回答

2

沒有必要阻止兩個線程,其中一個就足夠了:只需要一個actor來協調對那個(可怕的不可靠)API的許多調用,並在Futures中啓動它們(因爲cmbaxter建議你不要使用相同的ExecutionContext作爲演員正在運行,我會使用專用的)。這些期貨應該再使用firstCompletedOf一個超時未來組合:

import akka.pattern.after 
import context.system.scheduler 
import scala.concurrent.duration._ 

implicit val ec = myDedicatedDangerousActivityThreadPool 
val myDangerousFuture = ??? 
val timeout = after(1.second, scheduler(throw new TimeoutException) 
val combined = Future.firstCompletedOf(myDangerousFuture, timeout) 

然後,你管這回你的演員一些適當的方式,例如將其結果值映射到消息類型或任何您需要的內容,並記錄有多少是優秀的。我建議在Circuit Breaker中包裝myDangerousFuture以提高故障情況下的響應速度。