Lesson 4: What is the Poison Pill message and how to work with it.
In this lesson, we will consider the PoisonPill
message and how it differs from the Stop
message.
Stop
and PoisonPill
messages used to terminate the actor and stop the message queue. Both of these messages force the actor to stop processing incoming messages, and send a stop message to all of its child actors, and wait until they are finished. Then, send our code a message Stopped
that signals the actor’s complete shutdown. Keep in mind that all future messages sent to our actor’s address will be forwarded to dead letters mailbox.
Stop
will stop the actor immediately, ignoring if there are other user messages present in the mailbox.
PoisonPill
is a user-level message that is placed on the mailbox queue. and processed in order just like any other user message. So you can use that to gracefully stop an actor after all existing messages have been processed.
Let’s see how we can send a message PoisonPill
to our actor PlaybackActor
.
Let’s open our project and add the sending of the message PoisonPill
to the class Program
. You can do it with the help of Poison()
method
system.Root.Poison(pid);
As a result, we should get the following code.
class Program
{
static void Main(string[] args)
{
var system = new ActorSystem();
Console.WriteLine("Actor system created");
var props = Props.FromProducer(() => new PlaybackActor());
var pid = system.Root.Spawn(props);
system.Root.Send(pid, new PlayMovieMessage("The Movie", 44));
system.Root.Poison(pid);
Console.ReadLine();
}
}
Now we need to edit the PlaybackActor
so that it can handle the Stopped
message.
public class PlaybackActor : IActor
{
public PlaybackActor() => Console.WriteLine("Creating a PlaybackActor");
public Task ReceiveAsync(IContext context)
{
switch (context.Message)
{
case PlayMovieMessage msg:
Console.WriteLine($"Received movie title {msg.MovieTitle}");
Console.WriteLine($"Received user ID {msg.UserId}");
break;
case Stopped msg:
Console.WriteLine("actor is Stopped");
break;
}
return Task.CompletedTask;
}
}
Let’s launch our app and see what happened.
Let’s replace Poison()
call with Stop()
and lunch our app to see what happened.
- system.Root.Poison(pid);
+ system.Root.Stop(pid);
As you can see, the actor succesfully completed job.