【问题标题】:Akka 2.6 Actor Discovery In A Non-Actor Class (Get ActorRef Outside ActorSystem)Akka 2.6 非 Actor 类中的 Actor 发现(在 ActorSystem 之外获取 ActorRef)
【发布时间】:2021-01-12 22:10:38
【问题描述】:

目前我正在使用 Akka,我有以下协议。

在我的协议中,我有一个只负责创建资源(房间和 gabblers)的服务器。这些资源被创建然后被访问。接下来,我想通过一个键找到相应的 Gabbler ActorRef 来发送消息,但这一次是从一个公开了一个不是演员的 API/方法的类中。我已经看过文档,令我难以置信的是,演员系统中没有一种方法可以从其层次结构中返回特定的演员来使用它。我已经阅读了接待员部分,虽然对我来说不是很清楚,但我看到它再次面向演员。 Akka中没有根据Actor的路径返回引用的方法吗?

package co.test;

import akka.actor.typed.ActorSystem;
import akka.actor.typed.javadsl.AskPattern;
import akka.actor.typed.receptionist.Receptionist;
import co.test.actors.ChatServer;

public class ChatServerApplication {

    public static void main(String[] args) {
        
        ActorSystem<ChatServer.ServerCommand> system = 
            ActorSystem.create(ChatServer.create(), "chat-server");
        
        system.tell(new ChatServer.NewEventRoom("room1"));
        system.tell(new ChatServer.AttendeeJoin("room1", "user1"));
        system.tell(new ChatServer.AttendeeJoin("room1", "user2"));
        system.tell(new ChatServer.AttendeeJoin("room1", "user3"));
        system.tell(new ChatServer.AttendeeJoin("room1", "user4"));
        system.tell(new ChatServer.AttendeeJoin("room1", "user5"));
        system.tell(new ChatServer.AttendeeJoin("room1", "user6"));
        system.tell(new ChatServer.AttendeeJoin("room1", "user7"));
        
        //ActorRef<Gabbler.Command> gabbler = get specific Gabbler ActorRef
        //gabbler.tell(new Gabbler.SendMessage("test");
    }
    
}

上图中的协议已经实现,但我无法理解上面的问题。

【问题讨论】:

    标签: java akka akka-typed


    【解决方案1】:

    一般来说,为了将数据从actors 获取到actor 系统之外(例如main 方法),您需要处理ask pattern。使用 ask 模式时,您需要设计消息协议来支持它,通常是通过使要被询问的消息具有 ActorRef&lt;ReplyMsg&gt; 字段(通常命名为 replyTo)。 akka.actor.typed.javadsl.AskPattern.ask 有效地创建了一个短暂的actor,将该actor 的ActorRef 注入到消息中,如果它在超时期限内收到一条消息,它会使用该消息完成一个CompletionStage

    在此应用程序中,由于您要路由从 mainsystem 演员的所有内容,因此您可以定义 ChatServer.GetAttendee 消息:

    // assuming that there's an interface Command {} already in ChatServer
    public class ChatServer extends AbstractBehavior<ChatServer.Command> {
      public static class GetAttendee extends Command {
        public final String room;
        public final String user;
        public final ActorRef<ChatServer.AttendeeIs> replyTo;
    
        public GetAttendee(String room, String user, ActorRef<ChatServer.AttendeeIs> replyTo) {
          this.room = room;
          this.user = user;
          this.replyTo = replyTo;
        }
      }
    
      public static class AttendeeIs {
        public final ActorRef<Gabbler.Command> ref
    
        public AttendeeIs(ActorRef<Gabbler.Command> ref) {
          this.ref = ref;
        }
      }
    }
    

    ChatServer 可能会在相应的ChatRoom 上传递消息)

    在您的main 中,您可以发送类似的询问

    String desiredRoom = "whatever";
    String desiredUser = "whoever";
    
    CompletionStage<ChatServer.AttendeeIs> getGabbler =
      AskPattern.ask(
        system,
        replyTo -> new ChatServer.GetAttendee(desiredRoom, desiredUser, replyTo),
        Duration.ofSeconds(15),
        system.scheduler()
      )
    
     CompletionStage<ActorRef<Gabbler.Command>> gabblerFuture =
       getGabbler.thenCompose(
         (ChatServer.AttendeeIs response) ->
           return CompletableFuture.completedFuture(response.ref)
       )
    
     ActorRef<Gabbler.Command> gabbler = gabblerFuture.toCompletableFuture().get()
    

    【讨论】:

    • 非常感谢 Levi 的回复。我了解解决我的问题的方法。但是我看到 ask 模式是同步的,这最终阻碍了 tell 模式提供的异步性的优化。由于我是 Akka 工具包的新手,所以要顺利前行并不容易。我正在寻找两种异步解决问题的可能性:
    • 1.与接待员一起,我可以生成一个散列来识别每个 Gabblers,并通过包含他们的 ID 的消息,接待员将路由它(我不知道有多优化)。 2. 我已经意识到 Streams 的重要性,现在将它们视为响应式工作的卓越工具,并将参与者视为实现它的资源,这让我付出了代价,但我必须进行更多调查才能找到解决方案。 Levi 您如何看待这两种方法?还是您认为我必须使用询问模式?
    • 最后,Levi,请原谅我问了这么多。使用 ask 方法,主要参与者(聊天服务器)将是所有参与者的发现参与者,如果不同参与者太多,主要参与者会很重。突然间你知道为什么如果有一个唯一的演员标识符(例如路径),就没有简单的 Map 和返回演员引用的方法了吗?
    • Ask 仅在您阻止等待响应的情况下是同步的:即您在期货回调中尽可能多地进行操作。
    • 在实践中使用接待员与通过主要参与者路由消息没有什么不同。它引入了一个瓶颈。
    猜你喜欢
    • 1970-01-01
    • 2017-04-02
    • 1970-01-01
    • 2018-01-21
    • 2023-04-02
    • 1970-01-01
    • 2021-07-22
    • 2013-06-15
    • 1970-01-01
    相关资源
    最近更新 更多