有一對夫婦的問題,我可以根據您的代碼示例中的問題,在這裏看到:
我能做些什麼類型的東西,當我覆蓋的定義默認管理程序行爲如何處理異常?
當使用ask
時,當我在等待的Future
上獲得Failure
結果時,我可以執行哪些類型的操作?
讓我們先從第一個問題第一個(通常是一個好主意)。當您重寫默認主管策略時,您可以更改處理子主角中某些未處理的異常類型的方式,以處理如何處理該失敗的子主角。前一句中的關鍵詞是unhandled
。對於正在做請求/響應的角色,您可能實際上想要處理(捕獲)特定的異常,並返回某些響應類型(或者上游未來失敗,稍後再處理),而不是讓它們不處理。當發生未處理的異常時,您基本上無法通過問題描述來回復發件人,發件人可能會收到TimeoutException
,因爲他們的Future
將永遠不會完成。一旦明確了你明確處理的內容,那麼在定義自定義主管策略時,可以考慮所有其他異常。這裏面塊這裏:
OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 10 seconds) {
case x: Exception => ???
}
你得到一個機會,一個異常類型映射到故障Directive
,它定義瞭如何將故障從監管的角度來處理。選項有:
停止 - 完全停止兒童演員和不發送任何消息給它
恢復 - 恢復失敗的孩子,而不是重新啓動從而保持其當前的內部狀態
重啓 - 類似恢復,但在這種情況下,舊的實例是扔掉一個新的實例構造和內部狀態復位(啓動前)
升級 - 上報了連鎖經營,向主管的父
所以我們可以說,鑑於一個SQLException
你想恢復並給予你要重新啓動,然後其他所有的代碼應該是這樣的:
OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 10 seconds) {
case x: SQLException => Resume
case other => Restart
}
現在第二個問題涉及當Future
本身返回Failure
響應時該怎麼做。在這種情況下,我想這取決於Future
的結果應該發生的情況。如果剩下的演員本身是負責完成HTTP請求(讓我們說,httpCtx上有一個complete(statusCode:Int, message:String)
功能),那麼你可以做這樣的事情:
ask(dbActor, ReadCommand(reqCtx, id)).mapTo[SomeObject] onComplete {
case Success(obj) => reqCtx.complete(200, "All good!")
case Failure(err:TimeoutException) => reqCtx.complete(500, "Request timed out")
case Failure(ex) => reqCtx.complete(500, ex.getMessage)
}
現在,如果其他演員的上游是負責完成HTTP請求和你需要給演員的迴應,你可以做這樣的事情:
val origin = sender
ask(dbActor, ReadCommand(reqCtx, id)).mapTo[SomeObject] onComplete {
case Success(obj) => origin ! someResponseObject
case Failure(ex) => origin ! Status.Failure(ex)
}
這種方法假定在成功塊,你首先要響應之前按摩結果對象。如果你不想這樣做,你想推遲處理結果向發送者,那麼你可能只是這樣做:
val origin = sender
val fut = ask(dbActor, ReadCommand(reqCtx, id))
fut pipeTo origin
我想我明白了,這裏真正的關鍵是理解什麼是未處理的 – graph1ZzLle