Monday 22 August 2016

Akka Part 1

Why Akka ?

Most of us have done multithreading in the past won’t deny how hard and painful it is to manage multithreaded applications or concurrent applications.
Having to deal with threads, locks, race conditions, and so on is highly error-prone and can lead to code that is difficult to read, test, and maintain.
It aches when you see that you don’t have a easier way to recover from errors in your sub-tasks OR those zombie bugs that you find hard to reproduce OR when your profiler shows that your threads are spending a lot of time blocking wastefully before writing to a shared state.

What is the Akka Framework?

Akka is a toolkit and runtime for building highly concurrent, distributed, and fault tolerant applications on the JVM. Akka is written in Scala, with language bindings provided for both Scala and Java.
Akka’s approach to handling concurrency is based on the Actor Model

WHAT ARE ACTORS?

Treat Actors like Employee and HR Department,Employee sits in some remote location and HR at some other location and they both interact with mails.
So what all happens ??

MESSAGING :

So employee sends an email to HR form his INBOX and HR replies to the email from his INBOX.


CONCURRENCY

Now, imagine there are multiple employees sending requests to multiple HR departments to handle different type of requests
Nothing changes actually. Everybody has their own mailbox.


FAILOVER.

There can be chances when any HR is on sick leave or something, So there has to to some one who can handle his work for that day, So a member of the same team
steps up and replied to employees queries.
Points to note :
  1. There could be a pool of Actors who does different things.
  2. An Actor could do something that causes an exception. It wouldn’t be able to recover by itself. In which case a new Actor could be created in place of the old one. Alternatively, the Actor could just ignore that one particular message and proceed with the rest of the messages.

MULTITASKING

There is a possiblity that the same HR is involved in medical incurance and employee engagement, So the same HR can handle multiple type of requests.

CHAINING.

There is a possibility that you have sent a mails to HR, and all the HR’s are sending you a consolidated mail containing resolution of all your queries.
i.e we an make an hierarchy that will be followed by the HR team for replying to any query.
So lets here define the ACTOR model.
  1. So employee and HR become our ACTOR’s
  2. Mailbox can be considered as a queue from which data is going to be taken up and processed.
  3. Mail messages are immutable objects.
  4. There is a component that delivers
    message composed in the source inbox to the recipient inbox, lets
    call it, Message Dispatcher.

Sunday 21 August 2016

AKKA (Actor Messaging) -Part 2

Now lets discuss the messaging part of Actors:



Broadly these are explained in the following six steps when a message is passed to the actor:
  1. Employee creates something called an ActorSystem
  2. It uses the ActorSystem to create something called as ActorRef. The message(MSG) is sent to the ActorRef (a proxy to HR Actor)
  3. Actor ref passes the message along to a Message Dispatcher
  4. The Dispatcher enqueues the message in the target Actor’s MailBox.
  5. The Dispatcher then puts the Mailbox on a Thread (more on that in the next section).
  6. The MailBox dequeues a message and eventually delegates that to the actual HR Actor’s receive method.
Let’s look at each step in detail now. You can come back and revisit these five steps once we are done.

The EmployeeActor Program.

Lets consider this Employee Actor as the main program and lets cal it . EmployeeActorApp.
As we understand from the picture, the Employee Actor,
  1. Creates an ActorSystem
  2. Uses the ActorSystem to create a proxy to the HRActor (ActorRef)
  3. Sends the Message to the proxy.
Let’s focus on these three points alone now.

Creating an Actor System

ActorSystem is the entry point into the ActorWorld. ActorSystems are through which you could create and stop Actors. Or even shutdown the entire Actor environment.

On the other end of the spectrum, Actors are hierarchical and the ActorSystem is also similar to the java.lang.Object or scala.Any for all Actors - meaning, it is the root for all Actors. When you create an Actor using the ActorSystem’s actorOf method, you create an Actor just below the ActorSystem.

The code for initializing the ActorSystem looks like.
val system=ActorSystem("HrMessageingSystem")  
The HrMessageingSystem is simply a name you give to your ActorSystem.

Creating a Proxy for HR Actor

val hrActorRef:ActorRef = actorSystem.actorOf(Props[HRActor])
The actorOf is the Actor creation method in ActorSystem. But, as you can see, it doesn’t return a HrActor which we need. It returns something of type ActorRef.

The ActorRef acts as a Proxy for the actual Actors. The clients do not talk directly with the Actor. This is Actor Model’s way of avoiding direct access to any custom/private methods or variables in the HrActor or any Actor for that sake.

To repeat, you send messages only to the ActorRef and it eventually reaches your actual Actor. You can never talk to your Actor directly.

Send a Message to the Proxy

Now that we have an actor system and a reference to the actor, we would like to send requests to the HR actor reference. We send the message to an actor using the ! also called Tell.
//send a message to the HR Actor
 hrActorRef ! Message.
The Tell is also called as fire-forget. There is no acknowledgement returned from a Tell.
When the message is sent to an actor, the actor’s receive method will receive the message and processes it further. receive is a partial function and has the following signature:
def receive: PartialFunction[Any, Unit]
The return type receive suggests it is Unit and therefore this function is side effecting.

Here is the sample program for what we have discussed till now:
object EmployeeActorApp extends App{
 //Initialize the ActorSystem
  val actorSystem=ActorSystem("HrMessageingSystem")

 //construct the HR Actor Ref
  val hrActorRef=actorSystem.actorOf(Props[HrActor])

 //send a message to the HR Actor
  hrActorRef!Message

 //Let's wait for a couple of seconds before we shut down the    system
  Thread.sleep (2000) 

 //Shut down the ActorSystem.
  actorSystem.shutdown()

}  
You’ll have to shutdown the ActorSystem or otherwise, the JVM keeps running forever. And I am making the main thread sleep for a little while just to give the HrActor to finish off its task.

The Message

We just told a Message to the ActorRef but we didn’t see the message class at all!
object Message{
  case class Message()
  case class Message(someString:String)
}
As we know, the Message is for the requests that come to the HrActor. The Actor would respond back with a MessageResponse.

Dispatcher & A Mailbox

The ActorRef delegates the message handling functionality to the Dispatcher. Under the hood, while we created the ActorSystem and the ActorRef, a Dispatcher and a MailBox was created. Let’s see what they are about.

MailBox

Ever Actor has one MailBox . As Per our analogy, every HR has one mailbox too. The HR has to check the mailbox and process the message. In Actor world, it’s the other way round - the mailbox, when it gets a chance uses the Actor to accomplish its work.

Also the mailbox has a queue to store and process the messages in a FIFO fashion - a little different from our regular inbox where the most latest is the one at the top.

Dispatcher

Dispatcher does some really cool stuff. From the looks of it, the Dispatcher just gets the message from the ActorRef and passes it on to the MailBox. But there’s one amazing thing happening behind the scenes :

The Dispatcher wraps an ExecutorService (ForkJoinPool or ThreadPoolExecutor). It executes the MailBox against this ExecutorService.

Check out this code snippet from the Dispatcher:
protected[akka] override def registerForExecution(mbox: Mailbox, ...): Boolean = {  
    ...
    try {
        executorService execute mbox
    ...
}

HR Actor

The MailBox, when it gets its run method fired, dequeues a message from the message queue and passes it to the Actor for processing.

The method that eventually gets called when you tell a message to an ActorRef is the receive method of the target Actor.

The HrActor is a rudimentary class which has a List of quotes and obviously the receive method which handles the messages.

HRActor.scala :
class HRActor extends Actor {
def receive  = {
    case s: String if(s.equalsIgnoreCase(“SICK”)=> println("Sick Leave Applied”)
    case s: String if(s.equalsIgnoreCase(“PTO”) => println("PTO applied “)
    }
 }
The HRActor’s receive method pattern matches for the Messages passed - the Message (actually, it is a good practice to pattern match the default case but there’s an interesting story to tell there)

All that the receive method does is to,
  1. Pattern match for Message
  2. Check the message
  3. Check the type of the Message
  4. Process the message based on the type of message.