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