将AKKA演员绑定到上下文

时间:2013-06-28 06:22:14

标签: akka actor

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

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

1 个答案:

答案 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。这显然非常简化,但我认为它可能与您想要的类似。