是否可以将一组AKKA演员绑定到某个上下文?
E.g。我有三个演员,他们每个都在实现状态机。这些actor在某些状态转换时相互发送消息。现在我想将这些状态绑定到上下文,例如用户上下文。所以我有一个用户(由userId表示),其中有一组绑定在某些状态的actor。只要存在此用户上下文,这些actor(或至少其状态)必须绑定到用户的上下文。这本身在AKKA中是可能的还是我必须坚持不同演员的用户状态?或者演员不是为这些用例而设计的?
答案 0 :(得分:3)
我不是百分百肯定我得到了你的要求,但无论如何我都会接受答案。演员系统本身就是层次化的。在层次结构中存在父/子关系,父母将是孩子的所有者(和主管)。如果您使用UserContext
actor作为三个子actor(您的FSM actor)的父级来建模您的系统,那么我想这些子项将绑定到此UserContext
actor实例。考虑这个简化的示例模型:
class UserContext extends Actor{
val stateA = context.actorOf(Props[StateA])
val stateB = context.actorOf(Props[StateB])
val stateC = context.actorOf(Props[StateC])
def receive = {
case _ =>
}
}
class StateA extends Actor{
def receive = {
case _ =>
}
}
class StateB extends Actor{
def receive = {
case _ =>
}
}
class StateC extends Actor{
def receive = {
case _ =>
}
}
如果以这种方式进行设置,则在创建此用户上下文实例时将启动状态子项,并且在用户上下文实例停止时也将停止状态子项。现在您只需要一些代码来确保系统中每个用户只有一个用户上下文。你可以这样做,以确保:
object UserContext{
def apply(username:String)(implicit system:ActorSystem):ActorRef = {
val ctx = system.actorFor("/user/" + username)
if (ctx.isTerminated){
try{
system.actorOf(Props[UserContext], username)
}
catch{
case InvalidActorNameException(msg) if msg.contains("unique") => apply(username)
}
}
else
ctx
}
}
此工厂对象确保当前未运行所提供用户名的用户上下文actor。如果是,它只返回ref。如果没有,它会启动它并将其绑定到用户的名称以供以后查找。
一旦你做了这样的事情,只需使用工厂查找UserContext
提供的用户名,然后通过它路由所有消息,并让它将消息委托给正确的子状态actor。这显然非常简化,但我认为它可能与您想要的类似。