Akka 如何重新启动阿克卡演员的自我?

Akka 如何重新启动阿克卡演员的自我?,akka,Akka,当子参与者收到自定义重新启动消息时,参与者应自行重新启动。 (目的是重置参与者成员变量,从db重新加载外部状态,但不清除参与者内部消息队列) 要实现重新启动,一个解决方法是子参与者抛出自定义异常,父参与者将其OneForOneStrategy配置为为此特定异常类型重新启动子参与者 我想知道,是否有更直接的方法来重新启动 其目的是重置参与者成员变量,从db重新加载外部状态 我想,这可能是最大的问题,因为加载外部状态可能需要时间,并且会阻塞操作,因此操作的结果是或应该是Future[]-因此,在将来

当子参与者收到自定义重新启动消息时,参与者应自行重新启动。
(目的是重置参与者成员变量,从db重新加载外部状态,但不清除参与者内部消息队列)

要实现重新启动,一个解决方法是子参与者抛出自定义异常,父参与者将其
OneForOneStrategy
配置为为此特定异常类型重新启动子参与者

我想知道,是否有更直接的方法来重新启动

其目的是重置参与者成员变量,从db重新加载外部状态

我想,这可能是最大的问题,因为加载外部状态可能需要时间,并且会阻塞操作,因此操作的结果是或应该是
Future[]
-因此,在将来加载时,您的参与者应该忽略所有其他消息,直到收到来自DB的状态为止

我认为
ActorCell#been
方法在这种情况下可能会对您有所帮助-因此您可以将receive方法更改为另一种方法,该方法将忽略其余消息,但带有DB状态或数据的消息除外,然后切换回常规接收

请参见下面的代码示例:

导入akka.actor.actor
导入akka.pattern_
导入scala.concurrent.Future
导入scala.collection.mutable
//数据库API和外部状态模型示例
案例类DbExternalState()
性状数据库{
def loadExternalState:未来[DbExternalState]
}
导入重启器_
类RestartActor(数据库:database)扩展了Actor{
私有变量state=ActorState()
private val suspendedMessages=mutable.Queue[Any]()
覆盖def接收:接收=默认接收
专用def defaultReceive:Receive={
案例重新启动=>restartActorStart()
}
/**
*等待接收到具有内部状态的消息,并忽略所有其他消息(将其放回un queue)
*/
私有def挂起接收:接收={
案例ExternalStateLoaded(状态)=>restartActorFinish(状态)
案例消息=>suspendedMessages.enqueue(消息)
}
专用def restartActorStart():单位={
导入context.dispatcher
context.been(suspendedReceive)
database.loadExternalState.map(ExternalStateLoaded)管道到自身
}
专用def restartActorFinish(dbExternalState:dbExternalState):单位={
state=ActorState.initial(dbExternalState)
context.been(defaultReceive)//返回到正常的消息处理流
suspendedMessages.foreach(message=>self!message)
suspendedMessages.clear()
}
}
对象重启器{
//重新启动
案例对象重启
案例类ExternalStateLoaded(状态:DbExternalState)
案例类ActorState(internalState:List[String]=Nil,externalState:DbExternalState=DbExternalState())
对象ActorState{
def初始值(externalState:DbExternalState):ActorState=ActorState(externalState=externalState)
}
}
请让我知道你的建议是正确的。
我希望这有帮助

您能否提供更多详细信息,请说明
重新启动
下的含义?是否要将参与者内部状态更改为初始状态、清除消息队列等?谢谢。如果演员在重启过程中不在,我也不介意,因为这很快。但最好有这个。我担心的是,由于内部状态有点复杂,重启使恢复变得更容易。顺便说一句:
case message=>self!消息
这不是在进行一个
接收重发
循环吗?@user650167是的,根据循环,您是正确的,将修复该问题。关于对复杂状态的关注:我不知道细节,但从我的观点来看,显式状态更改看起来比抛出异常要好,抛出异常并不是真正的异常或错误,而是期望的行为,以迫使系统重新启动参与者。您可以尝试执行的操作-将状态(如果是多个字段)提取到具有方法的某个类,该方法将返回空或默认状态,并仅保留在单个字段中,并在初始化期间将值更改为
default
。这有意义吗?对。我也不喜欢抛出异常的方法;这就是为什么我在这里寻找更好的解决方案。谢谢你的建议@用户650167不客气。我也更新了答案。如果你觉得它有用,请投票或接受,我也很感激。谢谢你提出有趣的问题!