Mar 14, 2014

Monitoring Akka Actor in Scala (basic introduction)

In this tutorial we will see how we can add a watch on a child Actor (i.e. get a notification when child Actor is killed). Refer following code.



It will give following output.

Will monitor actor here
Parent:Hello
Parent:
Parent:Hi
Child::PreStart
Child:Hello
[ERROR] [03/14/2014 00:29:18.190] [ActorWatchSystem-akka.actor.default-dispatcher-2] [akka://ActorWatchSystem/user/parent/child] Boom....
java.lang.Exception: Boom....
       at com.techcielo.scala.actor.Child$$anonfun$receive$2.applyOrElse(MonitorableActor.scala:57)
       at akka.actor.ActorCell.receiveMessage(ActorCell.scala:425)
       at akka.actor.ActorCell.invoke(ActorCell.scala:386)
       at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:230)
       at akka.dispatch.Mailbox.run(Mailbox.scala:212)
       at akka.dispatch.ForkJoinExecutorConfigurator$MailboxExecutionTask.exec(AbstractDispatcher.scala:506)
       at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
       at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
       at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
       at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

Child::PreRestart
Child::Poststop
Child::postRestart
Child::PreStart
Child:Hi
Got handle to child actor
Child::Poststop
Child Terminated
class akka.actor.DeadLetterActorRef
Shutting down system


Now let's see how this code works. In order to understand this we will go back and forth in our code.

-> From line 29 to 40 we are creating an Actor class called Parent. When this class is created it will create a Child Actor using context (line# 30) and will add a watch on this child (line# 31). Since we have added watch on child if this child is terminate notification/message will be sent to Parent and receive method will get a message Terminate(ActorRef) so line# 37 will be executed. This Parent Actor will be called by our main method and this Actor will first get the message. Once it gets method it will print the message and send it to Child Actor (line# 35). If message is anything other then text it will simply print text "Parent got a message" without any processing.

-> Line# 42 to 48 shows our Child Actor (which is created by Parent Actor on line# 30). This class will get message from parent. We have also over loaded life cycle methods preStart, postStop, preRestart and postRestart of this Actor class. When this Actor gets message from parent (and when message is received receive method of this class will be called) it will check if this message has some text or not. If this message is a blank message it will throw an Exception which in turn will force actor to restart and hence its preRestart and postRestart methods will be called.
If message is anything other than String it will simply print text "Child got a message" (line# 60)

-> In our main method (line# 10 to 28) we are creating our ActorSystem (line# 12) then creating an instance of Parent Actor (line# 13) with name parent. We will pass some text messages to this Actor (also by passing blank message we will force it Child Actor to restart on line#15).

-> On line# 18 we are getting access to Child Actor's reference directly and we are giving this class a PoisonPill on line# 20 which will kill this child class once it has processed all message it has received before getting PoisonPill.

-> Once all operations are completed we will shutdown the actor system. If your system is continuously processing data then you need not to shutdow the system.

So this was brief introduction to Akka using Scala for Java developers. Interested users can try developing application where they are continuously getting some data from some stream and wants to process this data in parallel by using Akka Actors.

Happy coding. :)