我面臨Akka監督演員的問題。當子actor在未來結果的onFailure方法中拋出異常時,主管不處理該錯誤(我想在出現ConnectException時重新啓動子進程)。Akka監督演員不處理異常當小孩演員在未來的onFailure內拋出異常
我使用的是Akka 2.3.7。
這是主管演員:
class MobileUsersActor extends Actor with ActorLogging {
import Model.Implicits._
import Model.MobileNotifications
override val supervisorStrategy =
OneForOneStrategy(maxNrOfRetries = 3, withinTimeRange = 1 minute) {
case _: java.net.ConnectException => {
Logger.error("API connection error. Check your proxy configuration.")
Restart
}
}
def receive = {
case Start => findMobileUsers
}
private def findMobileUsers = {
val notis = MobileNotificationsRepository().find()
notis.map(invokePushSender)
}
private def invokePushSender(notis: List[MobileNotifications]) = {
notis.foreach { n =>
val pushSender = context.actorOf(PushSenderActor.props)
pushSender ! Send(n)
}
}
}
這是兒童演員:
class PushSenderActor extends Actor with ActorLogging {
def receive = {
case Send(noti) => {
val response = sendPushNotification(noti) onFailure {
case e: ConnectException => throw e
}
}
}
private def sendPushNotification(noti: MobileNotifications): Future[WSResponse] = {
val message = "Push notification message example"
Logger.info(s"Push Notification >> $message to users " + noti.users)
PushClient.sendNotification(message, noti.users)
}
}
我試圖用一個akka.actor.Status.Failure(五)以通知發件人的是建議here,但沒有工作,例外保持未處理的主管。
作爲一種變通方法,我發現這種方式來得到它的工作:
class PushSenderActor extends Actor with ActorLogging {
def receive = {
case Send(noti) => {
val response = sendPushNotification(noti) onFailure {
case e: ConnectException => self ! APIConnectionError
}
}
case APIConnectionError => throw new ConnectException
}
private def sendPushNotification(noti: MobileNotifications): Future[WSResponse] = {
val message = "Push notification message example"
Logger.info(s"Push Notification >> $message to users " + noti.users)
PushClient.sendNotification(message, noti.users)
}
}
這是一個錯誤阿卡還是我做錯了什麼?
謝謝!
謝謝,您的解決方案與我找到的解決方法類似,這是我目前使用的解決方法(請參閱我的文章的最後部分),但我認爲Akka必須提供某些內容來處理而不是發送消息給自我然後拋出異常。 – 2014-11-22 19:48:12
@GabrielVolpe不客氣。我認爲,只要你在未來之內,你就不能將這種異常傳播給調用線程。它的設計是爲了不以這種方式破壞它;未來的身體會自己捕獲異常,而你不能將它發出。即使使用akka.actor.Status.Failure(e),您也必須捕獲它並自行包裝。但我希望有一個聰明的方法))) – ale64bit 2014-11-22 19:52:32