修改了阿卡的你好世界——为什么有这么多丢失的信息和死信

  • 本文关键字:信息 你好 世界 修改 java akka
  • 更新时间 :
  • 英文 :


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

[2013年7月23日22:22:45.924][Main akka.aactor.default-dispatcher-2][akka://Main/user/app/$Si]消息[net.clementlevalois.akkatest.Greeter$Msg]来自演员[akka://Main/user/app#1478796310]至演员[akka://Main/user/app/[Si#-1309206213]未交付。1.遇到死信。此日志记录可以关闭或调整配置设置为"akka.log死信"one_answers"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);
        }
    }
}

我将感谢在调试方面的任何帮助,以及关于在这里创建演员列表是否可以的建议。

正如@Noah敏锐地指出的,当App参与者收到DONE响应时,它正在停止自己。现在,stop只是阻止参与者接收更多的消息,但它仍然会处理停止之前邮箱中的内容,因此可能会处理1条以上的消息。一旦这个参与者停止,通过getSelf传递给另一个参与者的ActorRef现在指向DeadLetter,这就是为什么你开始看到消息被路由到死信的原因。如果您真的想完全测试这一点,那么每次在App actor中收到响应时,递减一个计数器(从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);
    }
  }
}

最新更新