224

Newbie question of Akka - I'm reading over Akka Essentials, could someone please explain the difference between Akka Stop/Poison Pill vs. Kill ? The book offers just a small explaination "Kill is synchronous vs. Poison pill is asynchronous." But in what way? Does the calling actor thread lock during this time? Are the children actors notified during kill, post-stop envoked, etc? Example uses of one concept vs. the other?

Many thanks!

LaloInDublin
  • 5,379
  • 4
  • 22
  • 26
  • 12
    rs_atl answered it very well, let me just add that nothing about actors is synchronous, not even context.stop(self). – Roland Kuhn Dec 13 '12 at 09:08
  • 1
    @RolandKuhn what about `context.become`? – Ionuț G. Stan Oct 23 '14 at 12:38
  • 3
    `context.become` designates the behavior to be applied to the next message, which means that it takes effect after the current message has been processed; in this regard it is quite like `context.stop(self)`. – Roland Kuhn Oct 23 '14 at 16:33

4 Answers4

341

Both stop and PoisonPill will terminate the actor and stop the message queue. They will cause the actor to cease processing messages, send a stop call to all its children, wait for them to terminate, then call its postStop hook. All further messages are sent to the dead letters mailbox.

The difference is in which messages get processed before this sequence starts. In the case of the stop call, the message currently being processed is completed first, with all others discarded. When sending a PoisonPill, this is simply another message in the queue, so the sequence will start when the PoisonPill is received. All messages that are ahead of it in the queue will be processed first.

By contrast, the Kill message causes the actor to throw an ActorKilledException which gets handled using the normal supervisor mechanism. So the behaviour here depends on what you've defined in your supervisor strategy. The default is to stop the actor. But the mailbox persists, so when the actor restarts it will still have the old messages except for the one that caused the failure.

Also see the 'Stopping an Actor', 'Killing an Actor' section in the docs:

http://doc.akka.io/docs/akka/snapshot/scala/actors.html

And more on supervision strategies:

http://doc.akka.io/docs/akka/snapshot/scala/fault-tolerance.html

Kamiel Wanrooij
  • 12,164
  • 6
  • 37
  • 43
rs_atl
  • 8,935
  • 1
  • 23
  • 28
  • 4
    excellent answer thank you, should be posted on the Akka tutorial! – LaloInDublin Dec 13 '12 at 21:37
  • 18
    Kill message does NOT cause actor to restart using normal supervisor mechanism unless you use non-default supervisor strategy because ActorKilledException resolves to Stop, not Restart. – lisak Oct 13 '13 at 13:15
  • Actually it is quite annoying because the only built-in way of restarting actors is throwing an Exception. – lisak Oct 13 '13 at 13:18
  • 1
    Or sending a PoisonPill from a supervising actor to the one that should be restarted and start it again. – lisak Oct 13 '13 at 13:49
  • Is there any difference if using `context.stop(self)`? – BAR Sep 04 '15 at 00:49
  • "send a stop call to all its children" - by sending a `PoisonPill` or using `context.stop(child)`? – scravy Jan 28 '16 at 12:05
  • 1
    It's worth noting that using a `PosionPill` with an actor which uses the `Stash` trait can cause the `PoisonPill` to be auto-handled before the actor has unstashed any stashed messages. See http://doc.akka.io/docs/akka/current/scala/persistence.html#Safely_shutting_down_persistent_actors – David Apr 26 '17 at 16:55
  • It should be noted that a `PoisonPill` sent to *x* `stop`s all children of *x* after all messages of *x* are processed. That means that not all messages of the children will complete. A `stop` only completes the current message. Each child might therefore `stop` while having messages left. – Noel Widmer Jan 05 '18 at 09:50
1

Use PoisonPill whenever you can. It is put on the mailbox and is consumed like any other message. You can also use "context.stop(self)" from within an actor.

JohnUK
  • 21
  • 2
0

PoisonPill asynchronously stops the actor after it’s done with all messages that were received into mailbox, prior to PoisonPill.

idonnie
  • 1,703
  • 12
  • 11
0

You can use both actor stop and poison pill to stop processing of actors, and kill to terminate the actor in its entirety. x.stop is a call you make in akka receive method, will only replace actor state with new actor after calling postStop. x ! PoisonPill is a method that you pass to actor to stop processing when the actor is running(Recommended). will also replace actor state after calling postStop. x.kill will terminate the actor and will remove the actor in the actor Path and replace the entire actor with a new actor.