Reputation: 625
Java/Akka here. I have the following actor:
public class MyActor extends AbstractActor {
private Logger log = LoggerFactory.getLogger(this.getClass());
public MyActor() {
super();
}
@Override
public Receive createReceive() {
return receiveBuilder()
.match(Init.class, init -> {
log.info("Sending myself a Poison Pill...");
self().tell(PoisonPill.getInstance(), self());
}).match(PoisonPill.class, poisonPill -> {
log.info("Got the Poison Pill...");
context().system().terminate();
}).build();
}
}
When it receives an Init
message, I see the following log statement written:
Sending myself a Poison Pill...
But I never see:
Got the Poison Pill...
Furthermore the app just sits there and does not shut down as expected. Is there something in my use of self().tell(PoisonPill.getInstance(), self())
which prevents it from receiving the message and shutting down?
Upvotes: 3
Views: 416
Reputation: 19527
The log message doesn't appear because PoisonPill
is an AutoReceivedMessage
. An AutoReceivedMessage
is a special type of message that Akka handles internally and is not meant to be pattern-matched in user code.
One way to shut down the actor system once the actor is "poisoned"/stopped is to override the actor's postStop()
method:
@Override
public Receive createReceive() {
return receiveBuilder()
.match(Init.class, init -> {
log.info("Sending myself a Poison Pill...");
self().tell(PoisonPill.getInstance(), ActorRef.noSender());
})
.build();
}
@Override
public void postStop() {
getContext().getSystem().terminate();
}
Upvotes: 5