0

是否可以将一组 AKKA 演员绑定到某个上下文?

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

4

1 回答 1

3

我不能 100% 确定我得到你的要求,但无论如何我都会尝试回答。演员系统本身是分层的。父/子关系存在于层次结构中,父级将是子级的所有者(和主管)。如果你用一个UserContextactor作为三个子actor(你的FSMactor)的父级来建模你的系统,那么我想孩子们将绑定到这个UserContextactor实例。考虑这个简化的示例模型:

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
  }
}

此工厂对象确保提供的用户名的用户上下文参与者当前未运行。如果是,它只返回那个 ref。如果没有,它会启动它并将其绑定到用户名以供以后查找。

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

于 2013-06-28T12:17:47.867 回答