将AKKA参与者绑定到上下文

将AKKA参与者绑定到上下文,akka,actor,Akka,Actor,有可能将一组阿克卡演员绑定到特定的上下文中吗 例如,我有三个参与者,他们每个人都在实现一个状态机。这些参与者在某些状态转换时相互发送消息。现在我想将这些状态绑定到一个上下文,例如用户上下文。因此,我有一个用户(由userId表示),他在某些状态下绑定了一组参与者。只要这个用户上下文存在,这些参与者(或者至少是他们的状态)就必须绑定到用户上下文。这在阿克卡本身是可能的,还是我必须坚持不同参与者的状态?或者演员不是为这些用例而设计的吗?我不能100%确定我是否理解了你的要求,但我还是要尝试一下答案。

有可能将一组阿克卡演员绑定到特定的上下文中吗


例如,我有三个参与者,他们每个人都在实现一个状态机。这些参与者在某些状态转换时相互发送消息。现在我想将这些状态绑定到一个上下文,例如用户上下文。因此,我有一个用户(由userId表示),他在某些状态下绑定了一组参与者。只要这个用户上下文存在,这些参与者(或者至少是他们的状态)就必须绑定到用户上下文。这在阿克卡本身是可能的,还是我必须坚持不同参与者的状态?或者演员不是为这些用例而设计的吗?

我不能100%确定我是否理解了你的要求,但我还是要尝试一下答案。演员制度本身就是继承人制度。继承权中存在父/子关系,父/子关系将是子关系的所有者(和监督者)。如果您使用一个
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
  }
}
此工厂对象确保所提供用户名的用户上下文参与者当前未运行。如果是,它只返回该引用。如果不是,它将启动该引用并将其绑定到用户名称,以便以后查找


一旦您这样做了,只需使用工厂查找所提供用户名的
UserContext
,然后通过它路由所有消息,并让它将消息委托给正确的子状态参与者。这显然是相当简化的,但我认为它可能与您想要的类似

我不能百分之百确定我是否得到了你的要求,但无论如何,我会尝试一个答案。演员制度本身就是继承人制度。继承权中存在父/子关系,父/子关系将是子关系的所有者(和监督者)。如果您使用一个
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
  }
}
此工厂对象确保所提供用户名的用户上下文参与者当前未运行。如果是,它只返回该引用。如果不是,它将启动该引用并将其绑定到用户名称,以便以后查找


一旦您这样做了,只需使用工厂查找所提供用户名的
UserContext
,然后通过它路由所有消息,并让它将消息委托给正确的子状态参与者。这显然是相当简化的,但我认为它可能与您想要的类似

谢谢,你的回答100%符合我的问题!谢谢,你的回答100%符合我的问题!