【问题标题】:Akka Typed : How to get an ActorRef to a local actor?Akka Typed:如何将 ActorRef 获取给本地演员?
【发布时间】:2021-10-27 15:15:50
【问题描述】:

我正在将现有应用程序从 Akka Classic 移植到 Akka Typed。最初,您可以使用 context.actorSelection().resolveOne() 获得对演员的引用

我知道在 Akka Typed 中不再支持此功能,我们应该使用 Receptionist 注册演员以供 ServiceKey 发现。

但是,我只想将消息发送到 local 演员,这是集群中每个节点上都存在的本地单例。我有它的本地路径,但没有直接引用它。这是因为它是由 Akka 管理系统创建的健康检查参与者。

从文档中可以看出,使用 Receptionist 为 ServiceKey 注册一个参与者可以使其对集群的所有成员可用。因此,如果我查询 ServiceKey,我将在所有节点上收到对单例参与者的引用。

似乎没有办法仅在本地注册Receptionist,并且在集群中发布这些内部引用似乎不必要地泄漏并违反封装。 从Receptionist 返回的Listing 中找出哪个 ref 是本地演员似乎也不容易。 我想用于注册的ServiceKey 可能是系统特定的?

我在这里错过了一个明显的解决方案吗?

【问题讨论】:

    标签: akka akka-cluster akka-typed


    【解决方案1】:

    在 Akka Management Actor 的特定情况下,因为该项目不依赖于 Akka Typed(因此涉及的 Actor 是 Classic Actor),您可以将 Typed ActorContext 视为 Classic ActorContext 并使用 @ 987654323@.

    从你的问题来看,我猜是 Java(在 Scala 中,隐式使这变得不那么冗长,也许可以澄清意图):

    akka.actor.typed.javadsl.Adapter.toClassic(context).actorSelection(path).resolveOne(timeout)
    

    对于只想解析 Typed 本地参与者的情况,我发现最有效的策略是将解析功能合并到创建 ActorSystem 时提供的行为中。想要找到的演员会在ActorSystem注册,其他演员可以向ActorSystem索取ActorRef

    这里的一个微妙之处是context.getSystem() 为您提供了一个扩展ActorRef<Void>ActorSystem<Void>。您可以通过在ActorSystem 上调用unsafeUpcast 来解决此问题,例如

    // Might not actually be syntactically valid Java, but hopefully the fix to make it
    // legal is obvious...
    ActorRef<MyActorSystemCommand> systemRef = context.getSystem().unsafeUpcast<MyActorSystemCommand>()
    

    请注意,正确获取ActorSystem 的消息类型非常重要:如果ActorSystem 的行为不接受该类型的消息,则actor 系统将崩溃(据我所知,发送消息时无法阻止actor系统关闭。

    这种方法的演变是定义一个仅限本地的接待员演员,该演员在ActorSystem启动时产生:希望与该接待员交互的演员通过上述方法获得其ActorRef,然后该演员处理解析。

    当然请注意,在这两种方法中(与集群感知 Receptionist 一样),只有明确选择像这样被解析的参与者是可解析的。这符合 Akka Typed 的一个基本主题:让演员更多地负责它向外界展示的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-15
      • 1970-01-01
      • 2013-11-22
      • 2021-05-16
      • 2019-04-23
      • 2011-11-17
      • 2015-10-01
      • 2019-09-24
      相关资源
      最近更新 更多