在 Akka 中修改了 hello world - 为什么有这么多丢失的消息和死信?

sei*_*cle 3 java akka

在 Akka 2.2 中完成初学者,尝试修改版的Hello World。修改是我创建了 1000 个演员而不是一个。运行它,我没有得到所有的 1000 hello worlds 返回,这个错误跟踪,重复了几条消息:

[07/23/2013 22:22:45.924] [Main-akka.actor.default-dispatcher-2] [akka://Main/user/app/$Si] 消息 [net.clementlevallois.akkatest.Greeter$Msg ] 从 Actor[akka://Main/user/app#1478796310] 到 Actor[akka://Main/user/app/$Si#-1309206213] 未交付。1 死信遇到。可以使用配置设置“akka.log-dead-letters”和“akka.log-dead-letters-during-shutdown”关闭或调整此日志记录。

两个班级:

public class App extends UntypedActor {

    @Override
    public void preStart() {
        // create the greeter actors
        List<ActorRef> actorRefs = new ArrayList();
        for (int i = 0; i < 1000; i++) {
            final ActorRef greeter = getContext().actorOf(Props.create(Greeter.class, i));
            this.getContext().watch(greeter);
            actorRefs.add(greeter);
        }
        // tell it to perform the greeting
        for (ActorRef actorRef : actorRefs) {
            actorRef.tell(Greeter.Msg.GREET, getSelf());
        }
    }

    @Override
    public void onReceive(Object msg) {

        if (msg instanceof DeadLetter) {
            System.out.println(msg);
        } else if (msg == Greeter.Msg.DONE) {
            // when the greeter is done, stop this actor and with it the application
            getContext().stop(getSelf());
        } else {
            unhandled(msg);
        }
    }

}



public class Greeter extends UntypedActor {

    String input;

    public static enum Msg {
        GREET, DONE;
    }

    public Greeter(int i) {
        input = String.valueOf(i);
    }

    @Override
    public void onReceive(Object msg) {
        if (msg == Msg.GREET) {
            System.out.println("Hello World! " + input);
            getSender().tell(Msg.DONE, getSelf());
        } else {
            unhandled(msg);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我将不胜感激任何有关调试的帮助,以及是否可以像此处那样创建演员列表的建议。

cmb*_*ter 5

正如@Noah 敏锐地指出的那样,当App演员收到DONE响应时,它正在停止自己。现在,停止只是阻止参与者接收更多消息,但它仍将处理停止之前其邮箱中的内容,因此可能会处理 1 条以上的消息。一旦这个actor被停止,ActorRef传递给另一个actor的那个getSelf现在就指向了DeadLetter,这就是为什么你开始看到消息被路由到deadletter。如果您真的想对此进行全面测试,请在每次收到Appactor的响应时递减一个计数器(从 1000 开始)。当它达到 0 时,您可以安全地停止它:

public class App extends UntypedActor {
  private int counter = 1000;

  @Override
  public void preStart() {
    // create the greeter actors
    List<ActorRef> actorRefs = new ArrayList();
    for (int i = 0; i < counter; i++) {
        final ActorRef greeter = getContext().actorOf(Props.create(Greeter.class, i));
        this.getContext().watch(greeter);
        actorRefs.add(greeter);
    }
    // tell it to perform the greeting
    for (ActorRef actorRef : actorRefs) {
        actorRef.tell(Greeter.Msg.GREET, getSelf());
    }
  }

  @Override
  public void onReceive(Object msg) {

    if (msg instanceof DeadLetter) {
        System.out.println(msg);
    } else if (msg == Greeter.Msg.DONE) {
        if (--counter <= 0){
          getContext().stop(getSelf());
        }

    } else {
        unhandled(msg);
    }
  }

}
Run Code Online (Sandbox Code Playgroud)