martinnovoty
martinnovoty

Reputation: 893

akka getContext(). become() HotSwap not receiving messages

having code in akka and playing with become() need to understand why it receive only first msg and then it ignores ...

package ping_pong;
import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;

public class PingPongActor extends AbstractActor {

    public static void main(String[] args) throws Exception {
        ActorSystem _system = ActorSystem.create("PingPongActorApp");
        ActorRef masterpp = _system.actorOf(Props.create(PingPongActor.class),                 "pp");

        masterpp.tell(PING, masterpp);
        System.out.println("after first msg");
        masterpp.tell(PING, masterpp);
        masterpp.tell(PING, masterpp);
        masterpp.tell(PING, masterpp);
        masterpp.tell(PING, masterpp);
        masterpp.tell(PING, masterpp);
        System.out.println("last msg");

    }

    static String PING = "PING";
    static String PONG = "PONG";
    int count = 0;

    @Override
    public Receive createReceive() {
        return receiveBuilder().match(String.class, ua -> {
            if (ua.matches(PING)) {
                System.out.println("PING" + count);
                count += 1;
                Thread.sleep(100);
                if (count <= 10) {
                    getSelf().tell(PONG, getSelf());
                }

                getContext().become(receiveBuilder().match(String.class, ua1 -> {
                    if (ua1.matches(PONG)) {
                        System.out.println("PONG" + count);
                        count += 1;
                        Thread.sleep(100);
                        getContext().unbecome();
                    }
                }).build());

                if (count > 10) {
                    System.out.println("DONE" + count);
                    getContext().stop(getSelf());
                }
            }
        }
        ).build();
    }
}

It gives result:

21:36:34.098 [PingPongActorApp-akka.actor.default-dispatcher-4] INFO akka.event.slf4j.Slf4jLogger - Slf4jLogger started after first msg last msg PING0 PONG1

the question is why it ignores the other PING or also PONG messages ... ?

Upvotes: 0

Views: 51

Answers (1)

Levi Ramsey
Levi Ramsey

Reputation: 20561

When you getContext().become, you are replacing the entire Receive for that actor, so

getContext().become(receiveBuilder().match(String.class, ua1 -> {
    if (ua1.matches(PONG)) {
        System.out.println("PONG" + count);
        count += 1;
        Thread.sleep(100);
        getContext().unbecome();
    }
}).build());

You are installing a Receive which will only respond to messages matching PONG.

As an aside: Thread.sleep is basically the single worst thing you can do in an actor, as it prevents the actor from doing anything and also consumes a dispatcher thread. It would be a much better idea to schedule a message to yourself in 100 millis which would then trigger the unbecome.

Upvotes: 2

Related Questions