【问题标题】:Getting an actor by name from ActorSystem or Context (Akka.NET)从 ActorSystem 或 Context (Akka.NET) 按名称获取演员
【发布时间】:2020-01-03 10:14:00
【问题描述】:

是否可以检查 ActorSystem 中是否存在演员?
我只是不想将 IActorRef 引用传递给每个演员的构造函数,并且希望有类似 GetOrCreate 方法来实例化所需的演员。所以它可能就像一个我会在整个 Actor 系统中使用的单例 Actor。

【问题讨论】:

    标签: actor akka.net


    【解决方案1】:

    您可以使用ActorSelection 来检查是否存在任何参与者,以要求其识别自己:

    var selection = Context.ActorSelection(actorPath);
    /// if there's no actor, this operation can timeout
    var reply = await selection.Ask<ActorIdentity>(new Identify(null), timeout);
    

    虽然这在任何地方都有效,即使跨越网络边界,您也不能“仅仅”从任何地方创建一个演员。为了创建 Actor,需要一个父级 - 一个 Actor 系统或另一个 Actor。

    获取或创建逻辑可以非常简单地从演员内部完成:

    IActorRef GetOrCreate(string childName)
    {
        var child = Context.Child(childName);
        if (Equals(child, ActorRefs.Nobody))
            child = Context.ActorOf(Props.Create(() => new ChildActor()), childName);
        return child;
    }
    

    如果你需要让它在分布式环境中工作,这个功能由Akka.Cluster.Sharding插件覆盖。

    【讨论】:

    • 这种方法很好,但是我需要在第一次创建actor路径后保留它,这提醒了全局静态上下文,这对于actor和集群环境来说不是最好的事情或者我弄错了?保持线程安全的静态存储并在需要检查actor路径时创建所需的actor是否可以?
    • 常见的做法是只检索一次IActorRef 并将其缓存在更接近必须使用它的实际位置的地方 - 拥有一个带有 key=>IActorRef 字典的演员是很常见的传播给整个系统的其他参与者。可以停止 Ofc 演员 - 在这种情况下 IActorRef 将无效。 watching 解决了这个问题:它适用于本地和远程参与者。
    【解决方案2】:

    ActorSelection 有一个名为“ResolveOne”的方法,用于检查演员的存在。根据文档:

    解析匹配此选择的 IActorRef。结果返回 作为一个使用 IActorRef 完成的任务,如果这样的参与者 存在。如果没有,则以失败 ActorNotFoundException 完成 演员存在或识别未在提供的范围内完成 超时

    这个方法可以这样使用:

    var actorRef = await Context.ActorSelection("Path of Actor !").ResolveOne(TimeSpan.FromSeconds(5));
    

    【讨论】:

      猜你喜欢
      • 2014-02-07
      • 1970-01-01
      • 2017-02-15
      • 2014-09-30
      • 1970-01-01
      • 2014-11-15
      • 2015-05-10
      • 1970-01-01
      • 2015-02-22
      相关资源
      最近更新 更多