Akka in .Net Core – Akka Messages

Akka.Net helps build a solution that can both scale-up as well as scale-out. And the key concept that makes it happens is the messaging infrastructure of Akka.Net.

Akka.Net does not provide guaranteed delivery, just like any other actor implementation. What is supports is the at most once delivery of the message. Which means the message is delivered zero or one time. This is the cheapest form of message delivery as well as the fastest.

But in Akka.Net the message ordering is supported per sender-receiver pair (a feature specific to Akka.Net implementation of Actor framework).

To follow along with this post, I would strongly suggest using reading my previous post: and Akka in .Net Core.

akka.net

Akka Message Communication

So far in the examples, I have created, I have just focused on the Tell method for sending messages. There is another method that helps with message communication, and that is Ask. Unlike Tell which is a fire and forget, Ask follows send and receive the pattern. Which technically is like polling and creates performance implications. And hence you will not see it often implemented.

To show how the Ask method works, I will create a new class AskPatternActor, which will override the OnReceive to print the incoming message.

public class AskPatternActor : UntypedActor 
{ 
    protected override void OnReceive(object message) 
    { 
        Console.WriteLine($"Message regeived {message}"); 
    } 
}

Furthermore I will update the Main method to use Ask on the actor for sending message. And since Ask follows send and receive pattern, I will fire the call in a separate thread using a Task.

class Program 
{ 
    static void Main(string[] args) 
    { 
        var actrsys = ActorSystem.Create("test-actor-system"); 
        var askRef = actrsys.ActorOf(Props.Create(), "ask-actor"); 
        var askTask = Task.Factory.StartNew(() => askRef.Ask("Ask Actor")); 
        askTask.Wait(); 
        Console.ReadLine(); 
    } 
}

Finally, we will see in the output console printing out the message.

ask actor

Akka.Net PoisonPill

Akka.Net has a special message type that is represented by the PoisonPill class. Using the PoisonPill.Instance we can stop an Actor. This is a very useful message when the supervisor wants to stop a subordinate actor.

The PosionPill messages are treated like any other message by the Akka.Net messaging infrastructure. This means it will not take any precedence over the other message already in the mailbox queue.

To test this I will use the same AskPatternActor class, just add an extra Console.WriteLine inside of OnReceive event handler. And I will also add the PostStop handler to print when the actor is stopped.

Finally, I will update the implementation of the Main method.

public class AskPatternActor : UntypedActor
    {
        protected override void PostStop()
        {
            Console.WriteLine("AskPatternActor PostStop method");
        }
        protected override void OnReceive(object message)
        {
            Console.WriteLine("Inside of AskPatternActor OnReceive method");
            Console.WriteLine($"Message regeived {message}");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var actrsys = ActorSystem.Create("test-actor-system");
            var askRef = actrsys.ActorOf(Props.Create(), "ask-actor");
            askRef.Tell(PoisonPill.Instance);
            Console.WriteLine("Main function");
            Console.Read();
        }
    }

When we run the code, we will never see the WriteLine statement inside of the OnReceive of the AskPatternActor. But we will see the output from the PostStop event handler.

ask pattern actor

Akka.Net Kill.Instance

For stopping an actor we can also use the special message type which is represented by the Kill class. We can send a Kill.Instance as message to an Actor. And this will stop the actor just like the PoisonPill.Instance message.

But the difference here is that the actor will through an exception of type ActorKilledException. And in this case, if there is any supervision strategy at the supervisor will kick in. I am yet to find a very good use case for using this. When I get it, I will update the post.

In terms of code, I will use the same AskPatternActor class as an actor. But I will just change the Main method to pass the Kill.Instance message.

class Program 
{ 
    static void Main(string[] args) 
    { 
        var actrsys = ActorSystem.Create("test-actor-system"); 
        var askRef = actrsys.ActorOf(Props.Create(), "ask-actor"); 
        askRef.Tell(Kill.Instance); 
        Console.WriteLine("Main function"); Console.Read(); 
    } 
}

In this case, along with stopping the actor, we will also receive the ActorKilledException.

akka.net poison message

Conclusion

In this post, I have gone through a few concepts related to Akka.Net messaging. The logical next step would be to start looking into remote actors. So in the next post, I will start working with remote actors.