【问题标题】:Binding AKKA actors to context将 AKKA 演员绑定到上下文
【发布时间】:2013-06-28 06:22:13
【问题描述】:

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

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

【问题讨论】:

    标签: akka actor


    【解决方案1】:

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

    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 以获取提供的用户名,然后通过它路由所有消息,让它将消息委托给正确的子状态参与者。这显然非常简化,但我认为它可能与您想要的类似。

    【讨论】:

    • 谢谢,您的回答 100% 符合我的问题!
    猜你喜欢
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 2014-03-09
    • 2019-01-16
    • 2015-03-25
    • 2012-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多