3

在 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);
        }
    }
}

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

4

1 回答 1

5

正如@Noah 敏锐地指出的那样,当App演员收到DONE响应时,它会自行停止。现在,停止只是阻止参与者接收更多消息,但它仍会处理其邮箱中在停止之前的内容,因此可能会处理超过 1 条消息。一旦这个actor停止,ActorRef传递给另一个actor viagetSelf的那个现在指向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);
    }
  }

}
于 2013-07-23T22:46:36.757 回答