Actor System

Like in large organization actors form hierarchies. In my previous Actors post we discussed a bit on hierarchy. The Figure 1 shows the tree hierarchy structure while creating actors. Therefore each actor will always contain a parent actor, which is a supervised actor. We will take supervise actor in a separate post and discuss.

image
Figure 1 - Akka Hierarchical Structure

The main objective of this above tree hierarchy structure is to make small process components (micro level services). It has a big benefit of handling the failures in their parent level. Therefore it will allow us to keep our application alive.

The top-level actors are lived within the Error Kernel layer. So until it reaches to the top-level actors the fully scaled application won’t shutdown. This pattern is extracted from Erlang Theories.

Through out our blog series we’ve seen several time and discussed about accessing the actors. Lets look in to deep on Actor selection and the path.

Actor System occupies a main role in Akka application.

image
Figure 2 - Actor System features

Everything is build up from ActorSystem. In Figure 2 shows the thing that ActorSystem is focusing.

  • Dead Letter Office : It’s an another Actor that lives within ActorSystem. This actor is created by Akka. In case if actors find any communication problems (A actors is not exist or not running), the message will ends up with Dead Letter Office.

  • System Guardian Actor : These actors are not created by us. It will be created by Akka internally to coordinate the whole system.

  • User Guardian Actor : We are now concern about actors. They can’t independently stay in Akka application. It will exist under a parent. Hence, User Guardian Actor is the parent of all Actors that we create from ActorSystem (using ActorSystem.actorOf() method)

  • Event Stream : This component lives on ActorSystem and it’s mainly used to log the messages.

  • Scheduler : When ever we create a scheduler that will created on ActorSytem.

  • Setting : All the setting and configuration for the System can be accessed using ActorSystem.

All these guardian actors are living to build the resiliency in the system.

When we are creating the “family” ActorSystem the User Guardian Actor is created.

val system = ActorSystem("family")

So if we need to travel through the tree to access the Actor, the parent-child relationship should be placed in the path.

/user/{parent}/{child}

##Actor Paths

The URL pattern is standard through the Akka application. For an example we are creating “mother” Actor, so the expaned URL path will be,

Akka://family/user/mother

If we are dealing with only single ActorSystem (lives on only in one machine), the location and port information won’t be useful. But when we are creating Clusters in Akka, machine information is essential. To access a remote machine and remote Actors the URL needs to be included with HOST, PORT.

Akka://family@{host}:{port}/user/mother

Now lets take the family members example again and expand it (Figure 3).

image
Figure 3 - Family Members

To implement in much more nicely we will use HOCON (Human-Optimized Config Object Notation) configuration specification. So lets add our entire actor configuration in src/main/resources.conf file.

akka{
  apartment{
    securityGuardName = "Vikey"
    familyMembers{
      motherName = "Mary"
      fatherName = "John"
      sonsNames = ["Roy", "Petter"]
      daughtersNames = ["Sally", "Victoriya"]
    }
  }
}

It’s very challenging task to test the micro level services. But Akka provides us to log all the flow by adding the following configuration,

{
 loglevel = DEBUG
   actor {
     debug {
       lifecycle = on
     }
}

Therefore when we run it will log all the operations:

[DEBUG] [08/23/2015 19:44:51.643] [family-akka.actor.default-dispatcher-4] [akka://family/system] now supervising Actor[akka://family/system/deadLetterListener#2131296836]
[DEBUG] [08/23/2015 19:44:51.645] [family-akka.actor.default-dispatcher-2] [akka://family/system/deadLetterListener] started (akka.event.DeadLetterListener@35cc941)
[DEBUG] [08/23/2015 19:44:51.658] [family-akka.actor.default-dispatcher-3] [akka://family/user] now supervising Actor[akka://family/user/familyMembers#-452406400]
[DEBUG] [08/23/2015 19:44:51.660] [family-akka.actor.default-dispatcher-4] [akka://family/user/familyMembers/Mary] started (com.tutorial.actorSystem.Mother@20318ba1)
...........

In this example familyMembers is a supervisor to all the child nodes/members. Since now actor configurations are provided in the conf file and to get the conf details the implementation will be like this:

motherName = Option(context.system.settings.config.getString(
      "akka.apartment.familyMembers.motherName"))
    context.actorOf(Props[Mother], motherName.get)

When comparing to the previous sample code the additional actors are the supervised actor and several child actors.

In this example code I have used two ways to select the actors.

  • context.actorSelection()
context.actorSelection(message) //FamilyMember.scala class line 62
  • Storing the actorRef object
fatherActor.get //FamilyMember.scala class line 63

I hope now you would have got a pretty good idea about the ActorSystem, actor hierarchy and the structure. In our next blog we will see how the fault tolerance is handled and implemented.

To download the sample code : Download

Blog Series