What is Akka.net
Apr8Written by:
2017/04/08 12:21 PM
What exactly is Akka.net? Well, Akka.net started as a line for line port of Akka from Scalar into C# with certain adaptations to bridge differences in language and platform features. Akka.net now is continuing to be developed as an open source C# project with many useful add-ons to help in concurrent and distributed programming.
Akka.net is based around the Actor model. In the Actor model everything is considered as an actor. This is similar in object-orientated programming where everything is considered as an object. In object-orientated programming things are typically executed sequentially, while the Actor model is inherently concurrent.
Here is what Wikipedia has to say in the introduction to what an Actor Model is
The actor model in computer science is a mathematical model of concurrent computation that treats "actors" as the universal primitives of concurrent digital computation: in response to a message that it receives, an actor can make local decisions, create more actors, send more messages, and determine how to respond to the next message received.
Source: Actor Model - https://en.wikipedia.org
Actors are like "micro processors". Multiple actors can all execute concurrently on multiple cores built into a laptop or server.
image from https://petabridge.com/blog/akkadotnet-business-case/
To read more about Akka.net Actors go to the Akka.net Docs on Actors
The Actor System
Akka.Net is an actor framework for .NET. Akka.net has a few system level actors which are created automatically for you. You do not have any control over them. They perform the same or similar functions as any other actor. Creating child actors, supervising child actors. These are called Guardian Actors. You have to create an Actor System in order to create your top level and child actors. Below is an example of creating an Actor System.
// make actor system
var MyActorSystem = ActorSystem.Create("MyActorSystem");
// create top-level actors within the actor system
Props commandProps = Props.Create<CommandActor>();
IActorRef commandActor = MyActorSystem.ActorOf(commandProps, "commandActor");
These actors will be supervised by the Akka.net Guardian Actors.
Creating A New Actor with PROPS
Props is an object used to create an actor. You use the Props object to create actors within the Actor System or within the scope of another actor. Props also act as a factory for recreating actors should they die.
There are different ways to create actors with Props. Here are a few examples.
If the actor has a default constructor, we can create an actor like this:
Props commandProps = Props.Create<CommandActor>();
If your actors have constructors that take parameters, then you have to use a different form of Props like this:
Props commandProps = Props.Create(=> new CommandActor(someParameter));
We then need a reference to our new actors. That's where IActorRef comes is. An IActorRef is a handle to an actor within the Actor System. These IActorRef can be passed around the Actor System.
Creating Child Actors
Creating child actors as either a top level actor of the Actor System or as a child actor of other actors we still use Props. We then get an IActorRef reference to the newly created actor. Using a factory method of the Actor System we can create and instantiate the actor. Here is an example:
IActorRef commandActor = MyActorSystem.ActorOf(commandProps, "commandActor");
By using the ActorOf factory method we supply the Props object and a string name of the actor. Once you have an IActorRef you can Tell or Ask the actor things. This is how you pass messages around the actor system.
What is an actor actually? Well it is merely an immutable class. That performs one thing and one thing only. Actors in C# are implemented by extending the ReceiveActor class and configuring what messages to receive using the Receive method. You can have multiple Receive methods. However, each has to have a unique signature. That is the T has to be of a different type. That way the actor knows which message it can handle. Here is an example:
using System;
using Akka.Actor;
namespace SampleActors.Actors
{
internal class CommandActor : ReceiveActor
{
private IActorRef _coordinator;
public CommandActor()
{
Receive<string>(str => StartProcessing(str));
}
private void StartProcessing(string str)
{
Console.WriteLine(str);
}
}
}
Sending Messages
Actors get stuff done by passing messages around. The simplest way to do this is to Tell or Ask the actor and send it a message. That message has to be immutable. It can be a simple type such as a string object or a custom class that you create yourself. Tell means "fire-and-forget", e.g. send a message asynchronously and return immediately. Ask sends a message asynchronously and returns a Future representing a possible reply. Message ordering is guaranteed on a per-sender basis. I will cover Tell in this post. To find out more read the Akka.net Docs on Working with Actors.
When you Tell or Ask an actor to do stuff by sending it a message, you also have the opportunity of sending your own IActorRef. This will allow the receiver actor to be able to respond to your message, since the sender reference is sent along with the message.
Tell: Fire and Forget
Tell is the preferred way of sending messages. Fire and forget means no blocking or waiting for messages to complete. The parent actor can then carry on doing other stuff while the child actor is doing it's stuff. This gives you the best concurrency and scalability.
Here is an example:
commandActor.Tell("Hello Akka World", Self);
The sender reference is passed along with the message and available within the receiving actor via its Sender property. Inside of an actor it is usually Self who shall be the sender. Inside the receive actor you can access the sender actor via the Sender property. You don't have to pass an IActorRef to the receive actor. This is optional.
The receive actor then processes the message by executing the Receive method. Which method gets used depends on the message type being passed. If a reply is needed outside of the actor use the Ask-Pattern. See Working with Actors for more information.
The Sample App
You can use NuGet to get your Akka.net references for your project. For an introduction to why we need Akka.net see my previous post on Getting Started With Akka.Net. Below is a complete, simple Demo of the concepts we covered above.
using System;
using Akka.Actor;
namespace DemoAkkaConsole
{
class Program
{
static void Main(string[] args)
{
// make actor system
var MyActorSystem = ActorSystem.Create("MyActorSystem");
// create top-level actors within the actor system
Props commandProps = Props.Create<CommandActor>();
IActorRef commandActor = MyActorSystem.ActorOf(commandProps, "commandActor");
commandActor.Tell("Hello Akka World");
Console.ReadLine();
}
}
internal class CommandActor : ReceiveActor
{
private IActorRef _coordinator;
public CommandActor()
{
Receive<string>(str => StartProcessing(str));
}
private void StartProcessing(string str)
{
Console.WriteLine(str);
}
}
}
blog comments powered by