Akka in .Net Core
During the initial days of software development, scalability was a major issue in the world. Organizations either purchased multiprocessor servers to scale up the existing system or they went on to buy multiple systems that can run in parallel. This was done in the hope of meeting the load in the scaled-out model.
Do you think it is easy to convert a system from scaled up to scaled-down version or vice versa? No, it isn’t easy as it involves low-level coding that needs to be done meticulously to tackle the problems related to concurrency and distributed computing.
This problem still exists in the modern era even after the advent of the cloud. This is where Akka comes into the picture and it provides an excellent approach to build concurrent and fault-tolerant systems. Let's see in detail what is Akka, what it brings to the table, and how to implement an Akka-based system in .Net Core.
Table of contents
- What is Akka?
- What is an Actor Model?
- Implementation of Akka in .Net Core
- Conclusion
What is Akka?
Akka is a toolkit that is designed to handle and build highly concurrent, distributed, and fault-tolerant systems. It is built with Scala and offers both Scala and Java APIs for developers. Its approach to developing a concurrent and distributed system is based on the Actor Model (which we will see in the next section).
Akka provides a layer between the Actor and the underlying domain system, in such a way that the actor’s role is to process the incoming messages. On top of it, the complexity of creating, handling, scheduling threads, synchronization are handled by the framework. This makes it easier for the developers to concentrate on the business logic rather than on the low-level implementation of the concurrency mechanisms.
Below are the major advantages of the Akka.
- Multithreaded and concurrent behavior without the need to code.
- Transparent communication between systems, and
- High availability and scalability based on demand.
What is an Actor Model?
Simply put, it is a model which helps to achieve concurrent computing more easily. It provides a set of rules on how the interaction should happen between system components. Similar to Object-Oriented Programming where the object plays a major role, here the actor plays a major role. All the actions are driven around the actor.
Actors have individual mailboxes, do not share the memory, they are stateful and isolated from each other. Along with this, actors can create new actors, send messages to other actors, and can decide what to do with the next message.
As far as fault tolerance is concerned, each actor comes with a supervisor. And the logic behind the Actor Model is not to code defensively for all failure scenarios (to handle them), instead, the errors have to be handled dynamically. Say, if an actor errors out, the supervisor will act and put the actor back to a known consistent state and bring the actor back into action by self-healing method. IIf multiple messages are sent to the same actor, then the messages are processed by the actor sequentially.
Implementation of Akka in .Net Core
In this section, we will implement a simple project which consumes the Akka package using a console-based application.
Step 1
Create a .Net Core-based Console application and provide a valid name to the project.
Step 2
Once the project is created, it will have a program.cs file and have contents as below.
And the folder structure of the project will look like below.
Step 3
Time to add the reference of the Akka inside the project. To consume the Akka services you need to install a NuGet package. To do that right-click on the project and select the Manage NuGet package option. Search for ‘Akka’ and install the package - ‘Akka’
Step 4
Create a business logic class that you wish to call and maintain by the Akka Actor Model. Here for simplicity and convenience, we are creating a class named Logic. It has a constructor and it expects the injection of the string parameter.
public class Logic
{
public Logic(string inputMessage)
{
Message = inputMessage;
}
public string Message { get; set; }
}
Step 5
The next step is to introduce the actor class by inheriting the ReceiveActor class from Akka.Actor reference. Here, in this example, LogicActor acts as the Actor model and processes the input message received from Logic and processes the business logic. The Actor model creates a new thread and processes the information in it. Along with that, we log messages when the actor starts and stops the process.
public class LogicActor : ReceiveActor
{
public LogicActor()
{
Receive<Logic>(x => { Console.WriteLine($"Thread - {Thread.CurrentThread.ManagedThreadId} Message received. {x.Message}"); });
}
protected override void PreStart() => Console.WriteLine("Actor started");
protected override void PostStop() => Console.WriteLine("Actor stopped");
}
Step 6
In the main method, the calling of the actor happens. To do that, an actor system has been created and a name has been provided. Secondly, an actor has been specifically created for handling the logic actor and a valid name has been provided to it too. Next, ‘tell’ the method through which the business logic is assigned to the actor for processing. This actor is responsible for maintaining all the threads in the application. Here, we introduce a thread sleep mechanism for 5 seconds, so that we can test the actor stopping log message.
static void Main(string[] args)
{
var actorSystem = ActorSystem.Create("partech-actor-system");
var actor = actorSystem.ActorOf<LogicActor>("logic");
actor.Tell(new Logic("Hello there!"));
Thread.Sleep(5000);
actorSystem.Stop(actor);
Console.ReadLine();
}
Step 7
Run the solution. Observe the result as it states the thread number which is being maintained and controlled by the actor to process the business logic. Along with that, the actor ‘start’ and ‘stop’ messages also appear on the console window just above and below the processed message.
Final words
Akka opens up a plethora of options to achieve concurrent and distributed systems. The best part you can achieve them without the need to code complex logics to maintain them.