简体   繁体   中英

Akka & Java - dead letters encountered

I'm trying to create an Akka Actors system where each actor may create several new child actors. For example: Actor A reads a 200K lines input file and for each line in it will assign that text line to Actor B. Actor B, depending on some business logic, will create Actor C and so on.

I'm facing a non consistant behavior when dispatching Actors B that at some point I get the error of:

Message [java.lang.String] without sender to Actor[akka://My-Akka/user/$a/$b#304462457] was not delivered. [1] dead letters encountered. This logging can be turned off

The error can start after reading (and dispatching 100 lines or 1000 lines). Every run is different.

The programs starts with some Master class:

ActorSystem system = ActorSystem.create("My-Akka");
ActorRef actorA= system.actorOf(Props.create(ActorA.class));    
actorA.tell("some text", ActorRef.noSender());

In Actor A I'm creating a router:

    Router router;
{
    List<Routee> routees = new ArrayList<Routee>();
    for (int i = 0; i < 5; i++) {
        ActorRef r = getContext().actorOf(Props.create(ActorB.class));
        getContext().watch(r);
        routees.add(new ActorRefRoutee(r));
    }
    router = new Router(new RoundRobinRoutingLogic(), routees);
}

And within the Actor A's createReceive function:

    @Override
public Receive createReceive() {
    return receiveBuilder()
            .match(String.class, message -> {
                        ....
                        String line;
                        while ((line = br.readLine()) != null) {
                            router.route(line, getSender());
                        }
                    }
                }

            })
            .match(Terminated.class, message -> {
                router = router.removeRoutee(message.actor());
                ActorRef r = getContext().actorOf(Props.create(ActorB.class));
                getContext().watch(r);
                router = router.addRoutee(new ActorRefRoutee(r));
            })
            .build();
}

And Actor B's createReceive function:

    @Override
public Receive createReceive() {
    return receiveBuilder()
            .match(String.class, s -> {
                System.out.println("got message " + s);
            })
            .matchAny(o -> logger.info("received unknown message"))
            .build();
}

I guess I'm missing here something. Why it seems like every time Actor A is able to send different number of messages to Actor B before it reaches a dead letter. Is it because the master program is terminating before all the actors are doing their jobs? If this is the case, what needs to be changed?

Thanks

Seems like the problem was due to running the program in a Junit contex that shut down the system at certain time and killing the actors.

Once I run the program in regular mode the problem was gone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM