Actor

It’s time to start concurrency programming with Actors. To get a better understanding of the basic mechanism lets see on Actor creation and their operations.

Actor, Props and ActorSystem are very essential components that needs to be imported to run an Akka application. In my previous post I have already explained the role of Actor. If you have missed it: Akka Concurrency.

ActorSystem: It’s like the heart for group of Actors. Therefore, in hierarchical ActorSystem plays the main role.

Props: It’s a configuration class that allows doing configuration to Actor.

Now lets take a small example and try to implement in AkkaSystem.

In Figure 1 shows a conversation scenario between Mother and Son in the morning. They are talking to each other; basically they are doing a job. So we will create Mother Actor and Son Actor to handle the communication.

image
Figure 1 - Conversation between Mother and Son

Actor base is a trait. Implementation of Mother Actor class is shown below. Actor trait has a declaration method called Receive without body. This method is used to trigger when messages are passed in between actors. When we extends Actor the Receive method need to be implemented to capture the message. Using the case’s the messages can be pattern matched inside the Receive method.

class Mother extends Actor{
override def receive: Receive = {
case "Hi Mom" => {
println("Mother : Hi Son, Good Morning!..")
}
}
}

The following below Actor implementation is for Son Actor.

class Son extends Actor{
override def receive: Receive = {
case "Woke up" => {
println("Son : Hi Mom, Good Morning!..")
}
}
}

If you see the above two actors there is not much different. The objective of this example is to show the communication between two actors. Once Son is awake he will greet his Mother and she will response to it.

Still we didn’t implement the message passing code inside the actors. Before going to that stage lets look at how Mother and Son Actor objects are been created in ActorSystem.

object TestConversation extends App{
val system = ActorSystem("family")
val mother = system.actorOf(Props[Mother], "mother")
val son = system.actorOf(Props[Son], "son")
son ! "Woke up"
Thread.sleep(500) //Bad code
system.shutdown() //Shutdown the system
}

The code clearly shows the creation of Actors inside our ActorSystem “famil”. As I initially mentioned using Props we are assigning names for our actors (Eg: mother, son). These actors are created in our local machine so that we can access the Actors using their defined names (If names are not given ActorSystem will generate a unique name. But if we need to select an actor its name or address should be used).

In ActorSystem path hierarchy the root guardian reside above all the actors and its denoted by its name “/”. “/user” is the guardian actor for all user-created top-level actors and the actors which are created using ActorSystem (Eg: ActorSystem.actorOf). Therefore to access Mother/Son Actors in this example we can use their addresses: Mother - /user/mother Son - /user/son.

Now according to our flow (Figure 1) Son once he woke up, he greets his mom. So, Son actor need to access Mother actor. There are several ways to implement to access the Mother actor. In this example lets use ‘actorSelection’.

‘actorSelection’ method can be accessed using ActorContext. Once we create the Actor class the context can be accessed from the super class.

context.actorSelection("/user/mother") 

We have now access to Mother Actor lets send a message. In scala style there are few different ways to send the message to an actor. Through out akka tutorial I’ll be using the implicit method in Actor class the bang “!” mark.

context.actorSelection("/user/mother") ! "Hi Mom"

Now Son Actor class implementation will look like this :

class Son extends Actor{
override def receive: Receive = {
case "Woke up" => {
println("Son : Hi Mom")
context.actorSelection("/user/mother") ! "Hi Mom"
}
}

The following implementation and the code snippets are not standard.

  • This is an example we are trying to understand the Actor’s job and the implementation.

  • To communicate in between Actors we normally won’t use raw String. Actors are not doing any process just println doesn’t count as job.

  • Normally within actors we tend to avoid Threads. Here to show the communication between two micro level service we are adding Threed.sleep().

To download the sample code : Download

Blog Series