Akka tutorials: Simple Actor example
Let’s get acquainted with Akka Actors. This tutorial is useful for you if you have tried to start working with Akka using its official documentation, but stuck there. I’ll try to deliver all information by small portions in a proportion 50/50 theory and practice. Scala will be used as a programming language.
Few words about Akka Actors
As you probably already know, Akka is a toolkit for building of distributed, concurrent, asynchronous and non-blocking systems (it’s a good time to read Reactive Manifesto). Yeah-yeah, I know it sounds pretty loud, but it is exactly so. I’ll definitely write a separate post for a clear explanation of each of these words.
The second thing which you should already know is an Actor
. What is it? How it works? What is its purpose? An Actor
is a some sort of an isolated entity which contains state, behavior, mailbox, children and a supervisor strategy. Really scary, isn’t it? All of these terms need to be ignored for now. Let’s think about an Actor
as about something what accepts and sends messages.
I’m confident, that after demonstration of examples below, you’ll be able to understand a nature of Actors and their internal mechanism on a beginners level.
This is the most simple way to make Akka available in a project using SBT.
name := """akkaTutorial""" version := "0.1" scalaVersion := "2.11.7" libraryDependencies ++= Seq( "com.typesafe.akka" %% "akka-actor" % "2.4.1" )
Now we can declare the first Actor
.
import akka.actor.Actor import akka.event.Logging class DrinkActor extends Actor { val log = Logging(context.system, this) def receive = { case "tea" => log.info("Tea time!") case "coffee" => log.info("Coffee time!") case _ => log.info("Hmmm...") } }
It’s very trivial and useless Actor
, but it illustrates an Actor declaration process. Let’s consider what we have done for this.
1. DrinkActor
class extends the Actor
trait. This is mandatory step for a declaration of new Actor
.
2. A receive
function defines a logic (behavior) of an Actor
. It has a PartialFunction[Any, Unit]
type.
PartialFunction[Any, Unit] works just with particular values.
So the DrinkActor
works with two String
particular messages: “tea” and “coffee”. For the rest of messages it logs “Hmmm…”
But how we can pass messages to an Actor
? In order to show this on practice we need to create an ActorSystem
and Props
.
Actor in action
After the Actor declaration, we can finally see how it works. For this purpose we need to know about two things. The first one is Props
. During Actor
initialization we can set some options. Props
is a configuration object for an Actor
, which contains information about a creator, routing, deploy… Let’s think about Props
like about a mandatory component for Actor
creation.
What about ActorSystem
? Why we can’t create an Actor
independently of the system? The answer is pretty simple, Actors work in a cooperation and they have some hierarchy. I’m planning to explain this in a separate article.
With help of ActorSystem
we can initialize Actors. As you remember an Actor
is an isolated entity. So we need to use a factory method actorOf
, it returns an object ActorRef
, which is a key to interaction with associated Actor
.
Let’s see the DrinkActor
in action:
import akka.actor.{Props, ActorSystem} object ActorDemo { def main(args: Array[String]): Unit = { val system = ActorSystem("drinks-system") val props = Props[DrinkActor] val drinkActor = system.actorOf(props, "drinkActor-1") drinkActor ! "tea" drinkActor ! "coffee" drinkActor ! "water" system.terminate() } }
Firstly I create an ActorSystem
with name “drinks-system”. Next I need Props
for the DrinkActor
. Then I can get an ActorRef
(drinkActor). Finally I start sending messages to the recently created DrinkActor
. In the last line I terminate the system.
After the run of this code you need to see in the console something like this:
[INFO] [01/18/2016 12:53:40.514] [drinks-system-akka.actor.default-dispatcher-3] [akka://drinks-system/user/drinkActor-1] Tea time! [INFO] [01/18/2016 12:53:40.514] [drinks-system-akka.actor.default-dispatcher-3] [akka://drinks-system/user/drinkActor-1] Coffee time! [INFO] [01/18/2016 12:53:40.515] [drinks-system-akka.actor.default-dispatcher-3] [akka://drinks-system/user/drinkActor-1] Hmmm...
Summary
I believe that this article was helpful for you. But we still have too many questions. That’s why I’m going to continue writing articles about Akka. Write your comments and remarks, it’s very important for me to receive your feedback.