In previous post I’ve explained briefly what actor model is and why it’s so fun. Today we’ll create our ActorSystem instance, learn what it is and send first messages to them. I hope it will be nice and easy start.

Actor System

Biggest being in akka.NET is instance of ActorSystem class. In terms of Hollywood actors – if you think ActorSystem, you mean director. ActorSystem should be created at the application start globally and usually is stored as some static singleton that is globally available. In my application I’ve created static class with method that handles creating of ActorSystem and some top-level, must-have actors.

public static class ActorModel { public static ActorSystem MainActorSystem { get; set; } //... public static void StartActorSystem() { MainActorSystem = ActorSystem.Create("MainActorSystem"); //... } } 1 2 3 4 5 6 7 8 9 10 public static class ActorModel { public static ActorSystem MainActorSystem { get ; set ; } //... public static void StartActorSystem ( ) { MainActorSystem = ActorSystem . Create ( "MainActorSystem" ) ; //... } }

You should create instance of ActorSystem only by it’s static Create method. I’ve used it’s basic overload that only needs string parameter which will be it’s name, there is also overload that takes config but we’ll cover configuration in separate post in some time. Reason for not using new ActorSystem is simple, Create() method have some underlying configuration and preparation processes inside. You can take a look what magic lies beneath this method on AKKA.NET github here and here.

Although my ActorSystem is called MainActorSystem you shouldn’t have secondary or supporting or any other ActorSystem in same application. It’s rather heavyweight and expensive object designed to be only one in scope of entire application. If you need to separate two or more segments from one another, consider using top-level actors as “managers” of sort that will distribute subtasks along their children and supervise them(we’ll cover supervision and actor hierarchies in one of the next posts) .

First Actors

In my project I have three main domains for now: Users, Tags and Content. I haven’t really started Content part yet so in same helper as above I’m creating two top-level/manager actors. And again I’m storing them in static fields because I want easy access to them, it’s not necessary because you can easily traverse actor hierarchies using their addresses but it’s helpful. And again, you can’t just write new SomethingActor. You need to use Props, because actor need to have Props, it’s obvious.

public static IActorRef UsersManagerActorRef { get; set; } public static IActorRef TagsManagerActorRef { get; set; } public static void StartActorSystem() { //.. UsersManagerActorRef = MainActorSystem.ActorOf(UsersManagerActor.Props, "UsersManagerActorName"); TagsManagerActorRef = MainActorSystem.ActorOf(TagsManagerActor.Props, "TagsManagerActorName"); } 1 2 3 4 5 6 7 8 9 public static IActorRef UsersManagerActorRef { get ; set ; } public static IActorRef TagsManagerActorRef { get ; set ; } public static void StartActorSystem ( ) { //.. UsersManagerActorRef = MainActorSystem . ActorOf ( UsersManagerActor . Props , "UsersManagerActorName" ) ; TagsManagerActorRef = MainActorSystem . ActorOf ( TagsManagerActor . Props , "TagsManagerActorName" ) ; }

So, we’re taking our MainActorSystem reference and using it’s ActorOf method to create actor that are being children of ActorSystem, they will have their children in the future and so on. It takes two parameters, second one is actor name and it’ll be part of ActorPath which is it’s address and we’ll cover that in detail in one of next two posts during upcoming week. First parameters is mentioned earlier Props. Those are object that are being used to create our actors instances and pass values to their constructors (which I don’t need so far, we’ll cover more about Props in detailed post about Actors, it’ll be one of two upcoming posts during upcomin week ). My props are static geters in actor classes to make their creation even simpler.

public class UsersManagerActor : ReceiveActor { //.. public static Props Props => Props.Create(() => new UsersManagerActor()); } 1 2 3 4 5 public class UsersManagerActor : ReceiveActor { //.. public static Props Props = > Props . Create ( ( ) = > new UsersManagerActor ( ) ) ; }

One thing that is worth mentioning, our UsersManagerActorRef and TagsManagerActorRef variables in above static helper are not of Type of actor. They have type of IActorRef and it’s special kind of reference. Main method that is exposed by IActorRef interface is Tell method which is exactly what we need to send our first message.

Sending message

In my application, in my NancyModules (equivalent of MVC Controllers) I’m creating some of my main domain objects like Tags during creation or subscribtion of any tag or User during every Authenthicated request. I’ve marked them with IDispatch interface because their main roles is to dispatch some messages to actors. So when Tag is being subscribed by any User I’m using few dispatchers one of them is CreateTagIfNotExistsDispatcher that sends simple message to TagsManagerActor which will create TagActor for current tag if it’s not already active, next Dispatcher is TagSubscribedDispatcher which will send information about new subscriber to appropriate TagActor and message about new subscribed tag to appropriate UserActor. Someday I’ll add more dispatchers that will notify other actors about other related events. Let’s not go into details, but if you want to take a look just go to my github. Let’s take a look at out first message and dispatcher that’ll send it.

public class CreateTagIfNotExistsDispatcher : DispatcherBase<Tag> { //.. public override void Dispatch(Tag item, string userName) { ActorModel.TagsManagerActorRef.Tell(new CreateTagIfNotExistsMessage(item.TagName)); } } 1 2 3 4 5 6 7 8 public class CreateTagIfNotExistsDispatcher : DispatcherBase < Tag > { //.. public override void Dispatch ( Tag item , string userName ) { ActorModel . TagsManagerActorRef . Tell ( new CreateTagIfNotExistsMessage ( item . TagName ) ) ; } }

public class CreateTagIfNotExistsMessage { public string TagName { get; private set; } public CreateTagIfNotExistsMessage(string tagName) { TagName = tagName; } } 1 2 3 4 5 6 7 8 9 public class CreateTagIfNotExistsMessage { public string TagName { get ; private set ; } public CreateTagIfNotExistsMessage ( string tagName ) { TagName = tagName ; } }

public class TagsManagerActor : ReceiveActor { public TagsManagerActor() { Receive<CreateTagIfNotExistsMessage>(msg => HandleCreateTagIfNotExistsMessage(msg)); } private void HandleCreateTagIfNotExistsMessage(CreateTagIfNotExistsMessage msg) { CreateTagActorIfNotExists(msg.TagName); } private IActorRef CreateTagActorIfNotExists(string tagName) { if (!Context.Child(tagName).IsNobody()) return Context.Child(tagName); else return Context.ActorOf(TagActor.Props, tagName); } public static Props Props => Props.Create(() => new TagsManagerActor()); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class TagsManagerActor : ReceiveActor { public TagsManagerActor ( ) { Receive < CreateTagIfNotExistsMessage > ( msg = > HandleCreateTagIfNotExistsMessage ( msg ) ) ; } private void HandleCreateTagIfNotExistsMessage ( CreateTagIfNotExistsMessage msg ) { CreateTagActorIfNotExists ( msg . TagName ) ; } private IActorRef CreateTagActorIfNotExists ( string tagName ) { if ( ! Context . Child ( tagName ) . IsNobody ( ) ) return Context . Child ( tagName ) ; else return Context . ActorOf ( TagActor . Props , tagName ) ; } public static Props Props = > Props . Create ( ( ) = > new TagsManagerActor ( ) ) ; }

Not so much going on there but it’ll be enough for warmup. Actors, messages, IActorRefs and other things that I’m briefly desrbing right now will get more detailed posts in near future.

In first code block we have mentioned dispatcher that have just one important method – Dispatch. It’s only role is to create new CreateTagIfNotExistsMessage and send it by invoking Tell method on our static IActorRef to TagsManagerActor. Akka will do it’s magic underneath and by using actor address will find our actor reference and pass our message to him.

Our tags manager is derived from ReceiveActor which is one of akka basic actor types. Long story short – ReceiveActor can receive messages and react to them as we see fit.

In our actor constructor we define what actor should do in case of this message. We’re using simple lamba to pass msg (which is of type CreateTagIfNotExistsMessage) to HandleCreateTagIfNotExistsMessage which pass tagName property from message to method CreateTagActorIfNotExists. Next part is quite interesting because we’re getting IActorRef from Context (it’s actor’s Context) by using it’s Child method. It will look for children with provided name and will return IActorRef regardless of child existence, that’s why we need to use IsNobody method and check our IActorRef because we don’t want to send our messages to Nobody. If IActorRef for current tagName will not lead anywhere we’ll create child actor using same pattern we know from our top-level actors, one difference being Context will be used instead of ActorSystem.

Summary

Working with actors is pretty easy to start and enjoy. In about half week or so I’m planning to release another post covering Actors in more detail and short afterwards I’m going to write about IActorRef and other ways to grab a contact to actor and send him something. If you want to keep in touch, feel free to follow me on my Facebook or Twitter. If you want to read about anything AKKA.NET related just ask me in the comments and I’ll see what I can do.

Have a nice day!