Reputation: 893
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
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