Distributed and concurrent systems are norms rather than exception these days. And there is no other better framework to build a distributed system than Akka. Akka is an implementation of Actor model. Akka encapsulates all the complex implementation for managing concurrency, fault-tolerance and performance needed for building a distributed system. Akka.Net is the .Net implementation of the Akka framework which is originally build for Java/Scala.
What is Actor Model
The actor model is model of concurrent computation. In an Actor model, the state of an actor can be modified by the actor itself. But actors can effect each other through messages. Actors are autonomous entity.
Actors have following characteristics:
1. Actors communicate through asynchronous messages only
2. Actors manages their own state
3. Actors decides how they respond to the message, and if it should create a child actor to manage the request
Why use Actor Model
Consider the challenges faced in building a concurrent distributed system
1. When you communicate within multiple components, how to make them fault tolerant
2. When a component failed to execute a command in a different thread, how to communicate it back to the main thread
3. Managing locks when multiple threads accesses a shared resource within a component
Actor implementation of Akka solves these challenges without us worrying about managing all the code ourselves.
Creating a .Net Core Application
In this series I will be working on creating a distributed system using Akka.Net. But I will first start with a basic .Net Core application with Akka.Net. And than introduce different features of Akka.
I will open Visual Studio 2017 and create a new .Net Core Console application named AkkaExample
. I will click on File -> New -> Project. And select .NET Core -> Console App (.NET Core).
After that I will open the Nuget package manager right clicking on the project and clicking on “Manage Nuget Packages”. This will open Nuget package manager window. Once the window is opened, I will search for Akka package.
Finally I will click Install to install the 1.3.6 version of the Akka package.
Creating first Actor class
First of all I will start with creating an Actor class. A basic implementation of Actor. I will create a class named FirstActor
. I will rename the class later with a more appropriate name.
1 2 3 4 5 6 7 |
class FirstActor : UntypedActor { protected override void OnReceive(object message) { Console.WriteLine($"Message received {message}"); } } |
Here, I have created my first actor deriving from UntypedActor
class provided by the Akka.Actor
namespace. And override the abstract OnReceive
method, which will provide the message sent from a different actor. I will just print out the message.
After that I will update the FirstActor
class to implement two other methods PreStart
and PostStop
. PreStart
will be called when the actor is getting started. The PostStop
will be called after the actor is stopped.
1 2 3 4 5 6 7 8 9 10 11 |
class FirstActor : UntypedActor { protected override void PreStart() => Console.WriteLine("Started actor"); protected override void PostStop() => Console.WriteLine("Stopped actor"); protected override void OnReceive(object message) { Console.WriteLine($"Message received {message}"); } } |
Creating and sending message to actor
After the actor class is created and ready, I will now create an instance of the actor class and send a message.
First of all I will have to create a actor system. And for that I will use the ActorSystem.Create
method in the Main function of Program
class.
1 |
var actrsys = ActorSystem.Create("test-actor-system"); |
After I get a handle of the actor system, its time to create my actor. But, the actor class cannot be directly instantiated. Instead we will have to use the ActorOf
method of the ActorSystem
class and Props.Create
to create an instance of the actor.
1 |
var firstactor = actrsys.ActorOf(Props.Create<FirstActor>(), "first-actor"); |
And finally I will use the Tell
method on the Actor to send the message to it.
1 2 3 4 5 6 7 8 9 10 |
class Program { static void Main(string[] args) { var actrsys = ActorSystem.Create("test-actor-system"); var firstactor = actrsys.ActorOf(Props.Create<FirstActor>(), "first-actor"); firstactor.Tell("test"); Console.ReadLine(); } } |
Now I will run the application and I can see two messages printed out in the console. The “Started actor” which is printed from the PreStart
method. And the “Message received test”, which is printed from the OnReceive
method of the actor.
Stopping an Actor
For stopping an actor, we can either do it from inside of the actor based on some message. Or use the ActorSystem.Stop
to stop the actor.
1 2 3 4 5 6 7 8 9 10 11 |
class Program { static void Main(string[] args) { var actrsys = ActorSystem.Create("test-actor-system"); var firstactor = actrsys.ActorOf(Props.Create<FirstActor>(), "first-actor"); firstactor.Tell("test"); actrsys.Stop(firstactor); Console.ReadLine(); } } |
This time when I run the application, I will also see the “Stopped actor” message in the end.
Conclusion
This is just getting the feet wet with the Akka.Net. I am going to cover all the features of Akka.Net that are relevant for the distributed system programming in this series.
In my next blog I am going to cover the remote actor concept.