Exception 阿克卡:我怎样才能抓住一个演员在另一个(非儿童)演员身上的失败?
我有两个演员: ProcessManager处理系统中的某些流程(例如,用户注册、购买等) 通知程序-如果ProcessManager中发生错误,应通知用户。 我需要捕获ProcessManager actor的失败(无论是什么原因,它都失败并停止了,例如,由于ActorInitializationException或达到的最大重新启动时间,ProcessManager actor停止了) 如何在通知程序中捕获ProcessManager参与者的终止(由于失败) 编辑 让我解释一下我的问题的背景 我正在创建PM actor in Play controller,并将消息发送给它(Tell),然后立即向用户返回Ok响应。PM actor创建另一个子actor,并在创建过程中引发ActorInitializationException。我需要通知用户(通过web套接字,使用Notifier actor)出现问题。当Exception 阿克卡:我怎样才能抓住一个演员在另一个(非儿童)演员身上的失败?,exception,akka,akka-supervision,Exception,Akka,Akka Supervision,我有两个演员: ProcessManager处理系统中的某些流程(例如,用户注册、购买等) 通知程序-如果ProcessManager中发生错误,应通知用户。 我需要捕获ProcessManager actor的失败(无论是什么原因,它都失败并停止了,例如,由于ActorInitializationException或达到的最大重新启动时间,ProcessManager actor停止了) 如何在通知程序中捕获ProcessManager参与者的终止(由于失败) 编辑 让我解释一下我的问题的背景
ProcessManager
actor永久停止时,您可以使用注册Notifier
actor以接收已终止的
消息Notifier
将需要对DeathWatch
的ProcessManager
参与者的引用,一种方法是将引用作为消息发送到ProcessManager
(这是安全的,因为ActorRef
是不可变和可序列化的)
类通知程序扩展了Actor{
变量processManager:选项[ActorRef]=无
def接收:接收={
案例aRef:ActorRef=>
if(processManager.isEmpty){
processManager=Some(aRef)
watch(aRef)//注册以“监视”流程管理器
}
案例终止=>
//process manager已永久停止
案例
}
}
对象演示扩展应用程序{
val actorSystem=actorSystem(“我的演员系统”)
val notifier=actorSystem.actorOf(Props(classOf[notifier]))
val processManager=actorSystem.actorOf(Props(classOf[processManager]))
通知程序!processManager//将processManager的引用发送给通知程序
...
processManager!“某些消息将失败并停止pm actor”
...
}
一个警告:在尝试创建ProcessManager
时,可能无法在引发ActorInitializationException
之前进行DeathWatch
注册
如果在
ProcessManager
的子级引发异常时需要向通知程序发送消息,请覆盖ProcessManager
中的主管策略,并将此消息作为策略的一部分发送。比如:
类ProcessManager扩展了Actor{
导入akka.actor.OneForOneStrategy
导入akka.actor.SupervisorStrategy_
导入scala.concurrent.duration_
覆盖val管理策略=
一对一策略(最大重复次数=10次,初始范围=1分钟){
案例:ActorInitializationException=>
val notifier=context.actorSelection(“/path/to/notifier”)
通知程序!自定义错误消息
停止
案例:异常=>上报
}
def接收:接收={
...
}
}
让我解释一下问题的背景。我正在创建PM actor in Play controller,并将消息发送给它(Tell),然后立即向用户返回Ok响应。PM actor创建另一个子actor,并在创建过程中引发ActorInitializationException。我需要通知用户(通过web套接字,使用Notifier actor),出现了问题。所以这个解决方案不会解决这个问题,但是谢谢。@moreo:Updated。
class ProcessManager extends Actor {
override def receive: Receive = {
...
}
}
class Notifier extends Actor {
override def receive: Receive = {
PROCESS MANAGER ACTOR FAILED AND STOPPED =>
// Here I need to catch failure of ProcessManager actor
// (it was failed and stopped for what ever
// reason, for example, because of ActorInitializationException
// or max restart time reached and Process manager actor was stopped).
//
// Then do some stuff, for example, send message to the client via web socket.
}
}
class MyController @Inject() (cc: ControllerComponents, actorSystem: ActorSystem)
(implicit exec: ExecutionContext) extends AbstractController(cc) {
// I need to catch failure of processManager in this actor.
val notifier = actorSystem.actorOf(Props(classOf[Notifier]))
def registerUser = Action.async {
// Actor may be stopped because of ActorInitializationException here
val processManager = actorSystem.actorOf(Props(classOf[ProcessManager]))
...
// OR it may be stopped here for any reason.
processManager ! "some message which will fail and stop pm actor"
Future.successfull(Ok("Thanks."))
}
}