Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Akka Cookbook
Akka Cookbook

Akka Cookbook: Recipes for concurrent, fast, and reactive applications

Arrow left icon
Profile Icon Mishra Profile Icon Héctor Veiga Ortiz
Arrow right icon
€41.99
Full star icon Full star icon Full star icon Full star icon Half star icon 4.2 (10 Ratings)
Paperback May 2017 414 pages 1st Edition
eBook
€8.99 €32.99
Paperback
€41.99
Subscription
Free Trial
Renews at €18.99p/m
Arrow left icon
Profile Icon Mishra Profile Icon Héctor Veiga Ortiz
Arrow right icon
€41.99
Full star icon Full star icon Full star icon Full star icon Half star icon 4.2 (10 Ratings)
Paperback May 2017 414 pages 1st Edition
eBook
€8.99 €32.99
Paperback
€41.99
Subscription
Free Trial
Renews at €18.99p/m
eBook
€8.99 €32.99
Paperback
€41.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Akka Cookbook

Diving into Akka

In this chapter, we will cover the following recipes:

  • Creating an Akka Scala SBT project from scratch
  • Creating and understanding ActorSystem
  • Defining the actor's behavior and state
  • Sending messages to actors
  • Asking for a result from an actor
  • Communication between actors
  • Creating a custom mailbox for an actor
  • Prioritizing messages that an actor receives
  • Creating a control-aware mailbox for an actor
  • Become/unbecome behavior of an actor
  • Stopping an actor

Introduction

In today's world, computer hardware is becoming cheaper and more powerful, as we have multiple cores on a single CPU chip. As cores keep on increasing, with the increasing power of hardware, we need a state of the art software framework which can use these cores efficiently.

Akka is such a framework, or you can say, a toolkit, which utilizes the hardware cores efficiently and lets you write performant applications.

As we are living in big data world, a lot of traffic comes to our servers, and we want our servers to respond in milliseconds instead of seconds. Akka is here to scale up the application as the load on it increases.

We want our application to run day and night continuously with high availability--Akka is here to build fault tolerance for our application.

We want to run our application on a cluster of multiple machines--Akka is here to scale out our application across the data center.

Can we do all of this using the Java multithreading model? Maybe.

Our assumption is that most of our readers have worked with the Java multithreading model, and they are aware of the fact that it is very difficult to write multithreaded concurrent applications. This is because we have to manage low-level details like locking an object, releasing the lock on the object, notifying, waiting for threads to join each other to complete a task, and freeing up resources that a thread holds. It is difficult for us to write multithreaded programs, because we have to focus more on thread management details instead of focusing on business logic only.

Akka is a toolkit for writing truly concurrent, fault-tolerant, distributed, and scalable applications, which can run for days, months, and years without stopping, and can heal themselves in case of failure. It is very hard to write concurrent applications using the plain Java multithreading model, which also satisfies fault-tolerant, distributed, and scalable properties. Akka provides a high-level of abstraction to build such an application that satisfy these properties.

Thus, Akka provides a basic unit of abstraction of transparent distribution called actors, which form the basis for writing resilient, elastic, event-driven, and responsive systems.

Let's see what is meant by these properties:

  • Resilient: Applications that can heal themselves, which means they can recover from failure, and will always be responsive, even in case of failure like if we get errors or exceptions
  • Elastic: A system which is responsive under varying amount of workload, that is, the system always remains responsive, irrespective of increasing or decreasing traffic, by increasing or decreasing the resources allocated to service this workload
  • Message Driven: A system whose components are loosely coupled with each other and communicate using asynchronous message passing, and which reacts to those messages by taking an action
  • Responsive: A system that satisfies the preceding three properties is called responsive

A system that satisfies all four properties is called a reactive system.

Properties of reactive system
For more information, see Reactive manifesto (http://www.reactivemanifesto.org).

Before starting with recipes, let's take a look at the following the actor properties:

  1. State: An actor has internal state, which is mutated sequentially as messages are processed one by one.
  2. Behavior: An Actor reacts to messages which are sent to it by applying behavior on it.
  3. Communication: An actor communicates with other actors by sending and receiving messages to/from them.
  1. Mailbox: A mailbox is the queue of messages from which an actor picks up the message and processes it.
An actor's anatomy

Actors are message-driven, that is, they are passive and do nothing unless and until you send messages to them. Once you send them a message, they pick a thread from the thread pool which is also known as a dispatcher, process the message, and release the thread back to the thread pool.

Actors are also asynchronous by nature; they never block your current thread of execution, and continue to work on another thread.

Visit the Wikipedia link for an actor model (https://en.wikipedia.org/wiki/Actor_model) for details.

Let's start making recipes.

Creating an Akka Scala SBT project from scratch

Assuming that readers are Scala developers, it is obvious they have knowledge of SBT (Simple Build Tool) to build a Scala project.

Getting ready

To step through this recipe, you will need SBT installed on your machine. No other prerequisites are required.

If you don't have SBT installed on your machine, please visit the SBT manual installation page(http://www.scala-sbt.org/release/docs/Manual-Installation.html), and follow the instructions for the operating system you have.

SBT is used for building Scala projects as we have Maven for Java projects. However, both SBT and Maven are capable of building Scala, Java projects.

In this book, we will build our projects on the Ubuntu Linux operating system.

How to do it...

  1. For creating an SBT project, we need to create a project directory, for example, Hello-Akka.

Following screenshot shows the creation of the project directory:

Creating the project directory
  1. Descend to the directory and run command sbt. We will enter into the sbt prompt mode, Now run the following commands one by one, as shown in the next screenshot:
      set name := "Hello-Akka"
set version := "1.0"
set scalaVersion: ="2.11.7"
session save
exit

This will create a build file called build.sbt and a target to put your class files into.

  1. Edit the build file, and add the Akka actor dependency as follows:
      libraryDependencies += "com.typesafe.akka" % 
"akka-actor_2.11" % "2.4.4"

We can select a specific Akka actor version against a specific Scala version in the maven repository:

Adding Akka dependency to build file
  1. Run the command sbt update; it will download the Akka dependency. Now we have the Akka actor's capabilities in our project, and we are ready to write reactive programs.

The SBT (Simple Build tool), as the name suggests is a widely used tool for building Scala projects.

In step one, we create a project directory where we keep our source files, project build definition, and target, where class files are kept for runtime execution.

In step two, we create a project build definition file, called build.sbt, by executing simple sbt command.

In step three, we add a library dependency in the build file for the Akka actor to enable Akka capabilities.

In step four, we download the Akka dependency using the sbt update command, and our project is now ready for writing Akka-based applications.

This is how we can set up an Akka-based project.

Creating and understanding ActorSystem

In this small recipe, we will create and understand an ActorSystem. Since we are done with our initial setup of the Hello-Akka project, we don't need to make another project for it. We need to import the SBT project in an IDE like IntelliJ Idea.

Getting ready

How to do it...

It is very easy to create an ActorSystem in Akka:

  1. Create a package com.packt.chapter1 inside the Hello-Akka src folder. We will keep all the source code in this package.
  2. Inside the package, create a file, say HelloAkkaActorSystem.scala, which will contain the code.
  3. Create a small scala application object, HelloAkkaActorSystem, and create an ActorSystem inside it:
        package com.packt.chapter1 
Import akka.actor.ActorSystem
/**
* Created by user
*/
object HelloAkkaActorSystem extends App {
val actorSystem = ActorSystem("HelloAkka")
println(actorSystem)
}
  1. Now, run the application in IntelliJ Idea or in the console. It will print the output as follows:
      akka://HelloAkka  
Downloading the Akka actor dependency
Here is a way to run a single Scala application using sbt from the console. Descend to the application root directory, and run the following command:
sbt "runMain com.packt.chapter1.HelloAkkaActorSystem"

How it works...

In the recipe, we create a simple Scala object creating an ActorSystem, thereafter, we run the application.

Why we need ActorSystem

In Akka, an ActorSystem is the starting point of any Akka application that we write.

Technically, an ActorSystem is a heavyweight structure per application, which allocates n number of threads. Thus, it is recommended to create one ActorSystem per application, until we have a reason to create another one.

ActorSystem is the home for the actors in which they live, it manages the life cycle of an actor and supervises them.On creation, an ActorSystem starts three actors:

  • /user - The guardian actor: All user-defined actors are created as a child of the parent actor user, that is, when you create your actor in the ActorSystem, it becomes the child of the user guardian actor, and this guardian actor supervises your actors. If the guardian actor terminates, all your actors get terminated as well.
  • /system - The system guardian: In Akka, logging is also implemented using actors. This special guardian shut downs the logged-in actors when all normal actors have terminated. It watches the user guardian actor, and upon termination of the guardian actor, it initiates its own shutdown.
  • / - The root guardian: The root guardian is the grandparent of all the so-called top-level actors, and supervises all the top-level actors. Its purpose is to terminate the child upon any type of exception. It sets the ActorSystem status as terminated if the guardian actor is able to terminate all the child actors successfully.
For more information on ActorSystem visit: http://doc.akka.io/docs/akka/2.4.1/general/actor-systems.html.

Defining the actor's behavior and state

In this recipe, we will define an actor, which will receive some messages, and apply its behavior to its state. After that, we will create that actor inside the actor system.

We will see what is meant by the terms behavior and the state of an actor.

Getting ready

To step through this recipe, we need to import the Hello-Akka project in any IDE, like intelliJ Idea, and ensure that SBT is installed on our machine to build and run the Scala project from the console.

How to do it...

  1. Open the project Hello-Akka in an IDE like intelliJ Idea, and create a Scala file, BehaviorAndState.scala, inside the package, com.packt.chapter1.
  2. Add an import to the top of the file: import akka.actor.Actor.

Inside the file, define the actor as follows:

        class SummingActor extends Actor { 
// state inside the actor
var sum = 0
// behaviour which is applied on the state
override def receive: Receive = {
// receives message an integer
case x: Int => sum = sum + x
println(s"my state as sum is $sum")
// receives default message
case _ => println("I don't know what
are you talking about")
}
}

Here, we are not creating an actor, we are only defining the state and behavior.

  1. From the previous recipe, we know that ActorSystem is the home for actors, and we know how to create an ActorSystem. Now, we will create the actor inside it.

Add the following imports to the top of the file:

        import akka.actor.Props 
import akka.actor.ActorSystem
object BehaviourAndState extends App {
val actorSystem = ActorSystem("HelloAkka")
// creating an actor inside the actor system
val actor = actorSystem.actorOf(Props[SummingActor])
// print actor path
println(actor.path)
}
  1. Run the preceding application from the IDE or from the console, and it will print the actor path.

You can run the application from the console using the following command:

      sbt "runMain com.packt.chapter1.BehaviorAndState"
akka://HelloAkka/user/$a

Here, HelloAkka is the ActorSystem name, user is the user guardian actor, that is, the parent actor for your actor, and $a is the name of your actor.

You can also give a name to your actor:

        val actor = actorSystem.actorOf(Props[SummingActor],
"summingactor")

If you run the application again, it will print the actor name as summingactor.

The output will be as follows:

akka://HelloAkka/user/summingactor  

How do we create an actor if it takes an argument in the constructor as shown in the following code:

        class SummingActorWithConstructor(intitalSum: Int)
extends Actor {
// state inside the actor
var sum = 0
// behaviour which is applied on the state
override def receive: Receive = {
// receives message an integer
case x: Int => sum = intitalSum + sum + x
println(s"my state as sum is $sum")
// receives default message
case _ => println("I don't know what
are you talking about")
}
}

For this, we use the following code:

        actorSystem.actorOf(Props(classOf[
SummingActorWithConstructor], 10), "summingactor")

How it works...

As we know from the previous recipe, the ActorSystem is a place where the actor lives.

In the preceding application, we define the actor with its state and behavior, and then create it inside Akka using the API provided by Akka.

In case of the summingactor, the state is the variable sum and the behavior is adding of the integer to the sum as soon as the message arrives.

There's more...

Sending messages to actors

Sending messages to actors is the first step for building a Akka based application as Akka is a message driven framework, so get started

Getting ready

In this recipe, we will learn how to send messages to actors. Prerequisites are the same as the previous recipes.

How to do it...

In the previous recipe, we created an actor which calculates the sum of integers:

        val actor = actorSystem.actorOf(Props[SummingActor],
"summingactor")

Now, we will send messages as integers to the summing actor, as follows:

        actor ! 1 

The following will be the output:

My state as sum is 1  

If we keep on sending messages inside a while loop, the actor will continue to calculate the sum incrementally:

        while (true) { 
Thread.sleep(3000)
actor ! 1
}

On sending messages inside a while loop, the following output will be displayed:

my state as sum is 1
my state as sum is 2
my state as sum is 3
my state as sum is 4
my state as sum is 5

If we send a string message Hello, this message will fall into the actor's default behavior case, and the output will be as follows:

I don't know what you are talking about  

How it works...

Actors have methods to communicate with each other actors like tell (!) or ask (?) where the first one is fire and forget and the second returns a Future which means the response will come from that actor in the future.

As soon as you send the message to the actor, it receives the message, picks up an underlying Java thread from the thread pool, does it's work, and releases the thread. The actors never block your current thread of execution, thus, they are asynchronous by nature.

There's more...

Asking for a result from an actor

In this recipe, we will ask the actor to give us the result that it computes. Prerequisites are the same as the previous recipes.

In the last recipe, you learnt how to send a message using the tell-and-forget pattern. In this recipe, you will learn how to get the result from an actor after it does something.

How to do it...

Let's define an actor that computes something, say, the Fibonacci of a number:

  1. Create a Scala file, FibonacciActor.scala, in the package com.packt.chapter1.
  2. Add import to the top of the file:
        import akka.actor.Actor 

Now we define an actor which computes the Fibonacci of a number:

        class FibonacciActor extends Actor { 
override def receive: Receive = {
case num : Int =>
val fibonacciNumber = fib(num)
}
def fib( n : Int) : Int = n match {
case 0 | 1 => n
case _ => fib( n-1 ) + fib( n-2 )
}
}
  1. As of now, we have defined the actor. To send the computed result back to the sender, we have to add one more line to the actor code:
        sender ! fibonacciNumber 

Now, notice the difference:

        class FibonacciActor extends Actor { 
override def receive: Receive = {
case num : Int =>
val fibonacciNumber = fib(num)
sender ! fibonacciNumber
}
def fib( n : Int) : Int = n match {
case 0 | 1 => n
case _ => fib( n-1 ) + fib( n-2 )
}
}

Actors, by their implementation, know the default immediate sender, that is, they know who has sent them the message.

  1. Create an application which asks for result from the actor.
  2. Add the following imports to the top of file:
        import akka.actor.{Props, ActorSystem} 
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.Await
import scala.concurrent.duration._
  1. Create an object, FibonacciActorApp as follows:
        object FibonacciActorApp extends App {  
implicit val timeout = Timeout(10 seconds)
val actorSystem = ActorSystem("HelloAkka")
val actor = actorSystem.actorOf(Props[FibonacciActor])
// asking for result from actor
val future = (actor ? 10).mapTo[Int]
val fiboacciNumber = Await.result(future, 10 seconds)
println(fiboacciNumber)
}
  1. Run the preceding application in the IDE-like intelliJ Idea or from the console, and you will get the following output:

How it works...

We create an actor that computes Fibonacci number, and sends the result to the sender who sent him the message to compute the Fibonacci.

In the actor receive block, we send the Fibonacci result back to the sender. Actors, by nature, know who has sent them the message, thus we always have the sender present in the context of the receive block.

When you send a message to the actor using a question mark (?), it returns a future promising that you will get the result when the operation would be completed.

We will learn about futures in later chapters.

There's more...

Communication between actors

In an Akka-based application, there are many actors and they will have some way to communicate among themselves..

In this recipe, you will learn how two actors communicate with each other. For this, we need to import the same project, Hello-Akka, in our IDE. Prerequisites are the same as in the previous recipes.

Getting ready

To step through this recipe we will import the Hello-Akka project in our IDE and other prerequisites are same as before.

How to do it...

We will create the following two actors here:

  • QueryActor: Sends a message to RandomNumberGenerator to generate a random number
  • RandomNumberGeneratorActor: Sends the generated random number to the QueryActor

The following are the steps for creating the actors:

  1. Create a Scala file, Communication.scala, in the package com.packt.chapter1.
  2. Create an object, Messages, which will contain the messages to be sent to the actors for communicating with each other.
  1. Add import to the top of the file:
        import akka.actor.ActorRef 

After adding the import add the code that follows:

        object Messages { 
case class Done(randomNumber: Int)
case object GiveMeRandomNumber
case class Start(actorRef: ActorRef)
}
  1. Define RandomNumberGeneratorActor, which generates a random number and sends it back to the sender.
  2. Add the two imports given next to the top of the file:
        import akka.actor.Actor 
import scala.util.Random._

Now add the code that follows:

        class RandomNumberGeneratorActor extends Actor { 
import Messages._
override def receive: Receive = {
case GiveMeRandomNumber =>
println("received a message to
generate a random integer")
val randomNumber = nextInt
sender ! Done(randomNumber)
}
}
  1. Create a queryActor, which sends messages to RandomNumberGeneratorActor and receives the random number:
        class QueryActor extends Actor { 
import Messages._
override def receive: Receive = {
case Start(actorRef) => println(s"send me the next
random number")
actorRef ! GiveMeRandomNumber
case Done(randomNumber) =>
println(s"received a random number $randomNumber")
}
}
  1. Create an application object, Communication, to see the output:
        object Communication extends App { 
import Messages._
val actorSystem = ActorSystem("HelloAkka")
val randomNumberGenerator =
actorSystem.actorOf(Props[RandomNumberGeneratorActor],
"randomNumberGeneratorActor")
val queryActor = actorSystem.actorOf(Props[QueryActor],
"queryActor")
queryActor ! Start(randomNumberGenerator)
}
  1. Now run the application in the IDE or from the console, and the output will be displayed as follows:
      send me the next random number
received a message to generate a random integer
received a random number 841431704

How it works...

In step two, we see there is message object, which contains messages to be sent to the actors. Actors will use these messages for communication.

In step three, we define RandomNumberGeneratorActor, which receives the message GiveMeRandomNumber, and sends it to the sender as follows:

    sender ! Done(randomNumber) 

In step four, we define QueryActor, which actually sends the message to RandomNumberGenerator, and receives the result in case of Done.

In step five, we create a test application to see the execution flow of the whole message.

There's more...

In the following recipes, we will see how actors implement the master-slave work pulling pattern.

Creating a custom mailbox for an actor

In this recipe, you will learn how to create a custom mailbox for an actor. As you're already aware, in Akka, each actor has its own mailbox-like queue from which it picks up the messages one by one, and processes them. There are some custom mailbox implementations provided by Akka, such as PriorityMailbox and controlAwareMailbox, other than the default mailbox.

There might be a situation when you want to control the way the actor picks up the message or anything else. We will create an actor mailbox that will accept messages from actors of a particular name.

Getting ready

To step through this recipe, we need to import our Hello-Akka project in the IDE-like intelliJ Idea. Prerequisites are the same as those in the previous recipes.

How to do it...

  1. Create a Scala file, say CustomMailbox.scala, in package com.packt.chapter1.

Add the following required imports to the top of the file:

        import java.util.concurrent.ConcurrentLinkedQueue 
import akka.actor.{Props, Actor,
ActorSystem,ActorRef}
import akka.dispatch.{ MailboxType,
ProducesMessageQueue,
Envelope, MessageQueue}
import com.typesafe.config.Config
  1. Define a MyMessageQueue, which extends trait MessageQueue and implementing methods:
        class MyMessageQueue extends MessageQueue { 
private final val queue = new
ConcurrentLinkedQueue[Envelope]()
// these should be implemented; queue used as example
def enqueue(receiver: ActorRef, handle: Envelope): Unit =
{
if(handle.sender.path.name == "MyActor") {
handle.sender ! "Hey dude, How are you?, I Know your
name,processing your request"
queue.offer(handle)
}
else handle.sender ! "I don't talk to strangers, I
can't process your request"
}
def dequeue(): Envelope = queue.poll
def numberOfMessages: Int = queue.size
def hasMessages: Boolean = !queue.isEmpty
def cleanUp(owner: ActorRef, deadLetters: MessageQueue) {
while (hasMessages) {
deadLetters.enqueue(owner, dequeue())
}
}
}
  1. Let's provide a custom mailbox implementation, which uses the preceding MessageQueue:
        class MyUnboundedMailbox extends MailboxType
with ProducesMessageQueue[MyMessageQueue] {
def this(settings: ActorSystem.Settings,
config: Config) = { this()
}
// The create method is called to create the MessageQueue
final override def create(owner: Option[ActorRef], system::
Option[ActorSystem]):MessageQueue = new MyMessageQueue()
}
  1. Create an application.conf file and put the below configuration. An application.conf file is used to configure Akka application properties and it resides in the project's resource directory.
        custom-dispatcher {  
mailbox-requirement =
"com.packt.chapter1.MyMessageQueue"
}
akka.actor.mailbox.requirements {
"com.packt.chapter1.MyMessageQueue" = custom-dispatcher-
mailbox
}
custom-dispatcher-mailbox {
mailbox-type = "com.packt.chapter1.MyUnboundedMailbox"
}
  1. Now define an actor that would use the preceding configuration, say, MySpecialActor. It's special, because it would talk to the actor whom it knows, and say hello to that actor only:
        class MySpecialActor extends Actor { 
override def receive: Receive = {
case msg: String => println(s"msg is $msg" )
}
}
  1. Define an actor who will try to talk to the special actor:
        class MyActor extends Actor { 
override def receive: Receive = {
case (msg: String, actorRef: ActorRef) => actorRef !
msg
case msg => println(msg)
}
}
  1. Create a test application, CustomMailbox, as follows:
        object CustomMailbox extends App  { 
val actorSystem = ActorSystem("HelloAkka")
val actor =
actorSystem.actorOf(Props[MySpecialActor].withDispatcher
("custom-dispatcher"))
val actor1 = actorSystem.actorOf(Props[MyActor],"xyz")
val actor2 =
actorSystem.actorOf(Props[MyActor],"MyActor")
actor1 ! ("hello", actor)
actor2 ! ("hello", actor)
}
  1. Run the application in the IDE or from the console, and you will get the following output:
      I don't talk to strangers, I can't process your request
Hey dude, How are you?, I Know your name,processing your request
msg is hello

How it works...

As you know, a mailbox uses a message queue, and we need to provide a custom implementation for the queue.

In step two, we define a class, MyMessageQueue, which extends the trait MessageQueue and the implementing methods.

We want our actor to receive messages from only those actors whose name is MyActor, and not from any other actor.

To achieve the aforementioned functionality, we implement the enqueue method, and specify that the message should be enqueued if sender name is MyActor, otherwise ignore the message.

In this case, we used ConcurrentLinkedQueue as the underlying data structure for the queue.

However, it is up to us which data structure we pick for enqueing and removing messages. Changing the data structure may also change the processing order of messages.

In step three, we define the custom mailbox using MyMessageQueue.

In step four, we configure the preceding mailbox with a custom-dispatcher in application.conf.

In step five and six, we define MySpecialActor, which will use the custom mailbox when we create it with the custom-dispatcher. MyActor is the actor which tries to communicate with MySpecialActor.

In step seven, we have two instances of MyActor, actor1 and actor2, which send messages to MySpecialActor.

Since MySpecialActor talks to only those Actors whose name is MyActor, it does not process messages from MyActor whose name is xyz, as you can see in the output.

Prioritizing messages that an actor receives

There are situations when you want your actor to process some particular messages first, and then move on to others. This means you want to give priority to some messages over others.

For such scenarios, Akka has comes up with priority mailbox, which lets you prioritize messages.

Getting ready

To step through this recipe, we need to import our Hello-Akka project in IDE-like IntelliJ Idea. Prerequisites are the same as those in previous recipes.

How to do it...

  1. Create a Scala file named PriorityMailBox.scala in package comi.packt.chapter1.
  2. Create an actor called MyPriorityActor as follows:
        class MyPriorityActor extends Actor { 
def receive: PartialFunction[Any, Unit] = {
// Int Messages
case x: Int => println(x)
// String Messages
case x: String => println(x)
// Long messages
case x: Long => println(x)
// other messages
case x => println(x)
}
}
  1. To prioritize the messages, create a priority mailbox as follows:
        class MyPriorityActorMailbox(settings:
ActorSystem.Settings, config: Config) extends
UnboundedPriorityMailbox (
// Create a new PriorityGenerator,
lower prio means more important
PriorityGenerator {
// Int Messages
case x: Int => 1
// String Messages
case x: String => 0
// Long messages
case x: Long => 2
// other messages
case _ => 3
})
  1. Add this configuration to application.conf:
        prio-dispatcher {  
mailbox-type =
"com.packt.chapter1..MyPriorityActorMailbox"
}
  1. Create an application, PriorityMailBoxApp, as shown in the following code:
        object PriorityMailBoxApp extends App { 
val actorSystem = ActorSystem("HelloAkka")
val myPriorityActor =
actorSystem.actorOf(Props[MyPriorityActor].withDispatcher
("prio-dispatcher"))
myPriorityActor ! 6.0
myPriorityActor ! 1
myPriorityActor ! 5.0
myPriorityActor ! 3
myPriorityActor ! "Hello"
myPriorityActor ! 5
myPriorityActor ! "I am priority actor"
myPriorityActor ! "I process string messages first,then
integer, long and others"
}
  1. Run the application in IDE or from the console. The following output will be displayed:
      Hello
I process string messages first,then integer, long and others
I am priority actor
1
3
5
6.0
5.0

How it works...

In step two, we just define an actor which processes Int, Long, String, and other messages.

In step four, we configure a prio-dispatcher with this MyPriorityActorMailbox.

In step five, we create an actor which will use the prio-dispatcher.

In step six, as we can see in the output, the string messages are processed first, because they were given highest priority.

Creating a control-aware mailbox for an actor

There are some situations when you want your actor to process a certain message first before any other message, at any point of time. This means that you can tell an actor to do some particular work before doing any other job.

Getting ready

To step through this recipe, we need to import our Hello-Akka project in IDE-like IntelliJ Idea. Prerequisites are the same as those of the previous recipes.

How to do it...

  1. Create a file, ControlAwareMailbox.scala, in package com.packt.chapter1.
  2. Add the following imports to the top of the file:
        import akka.dispatch.ControlMessage 
import akka.actor.{Props, Actor, ActorSystem}
  1. Create a control message case object as follows:
        case object MyControlMessage extends ControlMessage 
  1. Define an actor:
        class Logger extends Actor {  
def receive = {
case MyControlMessage => println("Oh, I have to process
Control message first")
case x => println(x.toString)
}
}
  1. Add the following configuration to application.conf:
         control-aware-dispatcher {  
mailbox-type =
"akka.dispatch.UnboundedControlAwareMailbox"
//Other dispatcher configuration goes here
}
  1. Create a test application in which we can send a message to the preceding application, and it will process the control message first:
        object ControlAwareMailbox extends App {  
val actorSystem = ActorSystem("HelloAkka")
val actor =
actorSystem.actorOf(Props[Logger].withDispatcher(
"control-aware-dispatcher"))
actor ! "hello"
actor ! "how are"
actor ! "you?"
actor ! MyControlMessage
}
  1. Run the application in IDE or from the console. You will get the following output:
      Oh, I have to process Control message first
hello
how are
you?

How it works...

In step three, we create an object, MyControlMessage, which extends the ControlMessage.

ControlMessage is a trait. The message which extends this trait will be handled on priority by ControlAwareMailbox. ControlAwareMailbox maintains two queues to allow messages that extend ControlMessage to be delivered with priority.

In step four, we create an actor which will handle ControlMessage.

In step five, we configure the control-aware-dispatcher in application.conf.

In step six. we create the actor with control-aware-dispatcher.

In step seven, we are able to see in the output that the actor processed ControlMessage first.

Become/unbecome behavior of an actor

In some situations, we want our actor to change its behavior based on its state. This means that there are cases where an actor receives a message, and if its state changes or transitions, it changes the way further messages should be handled.

Thus, using become/unbecome, we can hot swap the actor functionality at runtime.

Getting ready

To step through this recipe, we need to import the Hello-Akka project in the IDE-like IntelliJ Idea. Prerequisites are the same as those in previous recipes.

How to do it...

  1. Create a file named BecomeUnbecome.scala in package com.packt.chapter1.
  2. Add the following imports to the top of the file:
        import akka.actor.{Props, ActorSystem, Actor} 
  1. Define an actor which changes its behavior based on whether the state is true or false, as shown in the following code:
        class BecomeUnBecomeActor extends Actor { 
def receive: Receive = {
case true => context.become(isStateTrue)
case false => context.become(isStateFalse)
case _ => println("don't know what you want to say !! ")
}
def isStateTrue: Receive = {
case msg : String => println(s"$msg")
case false => context.become(isStateFalse)
}
def isStateFalse: Receive = {
case msg : Int => println(s"$msg")
case true => context.become(isStateTrue)
}
}
  1. Create a test application, BecomeUnBecomeApp, as follows:
        object BecomeUnBecomeApp extends App { 
val actorSystem = ActorSystem("HelloAkka")
val becomeUnBecome =
actorSystem.actorOf(Props[BecomeUnBecomeActor])
becomeUnBecome ! true
becomeUnBecome ! "Hello how are you?"
becomeUnBecome ! false
becomeUnBecome ! 1100
becomeUnBecome ! true
becomeUnBecome ! "What do u do?"
}
  1. Run the application in an IDE like IntelliJ Idea or from the console; the output will be as follows:
      Hello how are you?
1100
What do u do?

How it works...

In step two, we define an actor, which changes its state to handle string and integer values.

If the state is true, we set the behavior as context.become(isStateTrue), and it starts handling string messages. If the state is false, we set the behavior as context.become(isStateFalse), and it starts handling integer messages.

In step four, we create the actor and send it to see if the output matches the functionality.

Stopping an actor

It is obvious that an actor has to be shut down gracefully after it has processed all the messages or on application shutdown.

Getting ready

To step through this recipe, we need import the Hello-Akka project in an IDE like IntelliJ Idea. Prerequisites are the same as those in previous recipes.

How to do it...

  1. Create a file, Shutdown.scala, in package com.packt.chapter1.
  2. Add the following imports to the top of file:
        import akka.actor.{PoisonPill, Props, ActorSystem, Actor} 
  1. Create a case object, Stop, as the message:
        case object Stop 
  1. Define an actor, ShutdownActor, as follows:
        class ShutdownActor extends Actor { 
override def receive: Receive = {
case msg:String => println(s"$msg")
case Stop => context.stop(self)
}
}
  1. There are two ways we can stop the actor:
  • Using PoisonPill
  • Using context.self(actorRef)

Create an actor and send it a message as shown in the following code:

        object ShutdownApp extends App{ 
val actorSystem = ActorSystem("HelloAkka")
val shutdownActor1 =
actorSystem.actorOf(Props[ShutdownActor],
"shutdownActor1")
shutdownActor1 ! "hello"
shutdownActor1 ! PoisonPill
shutdownActor1 ! "Are you there?"
val shutdownActor2 =
actorSystem.actorOf(Props[ShutdownActor],
"shutdownActor2")
shutdownActor2 ! "hello"
shutdownActor2 ! Stop
shutdownActor2 ! "Are you there?"
}
  1. Run the preceding application, and you will get the following output:
      hello
hello
[INFO] [05/22/2016 20:39:53.137] [HelloAkka-akka.actor.default-
dispatcher-4] [akka://HelloAkka/user/shutdownActor1] Message
[java.lang.String] from Actor[akka://HelloAkka/deadLetters] to
Actor[akka://HelloAkka/user/shutdownActor1#417818231] was not
delivered. [1] dead letters encountered.

[INFO] [05/22/2016 20:39:53.138] [HelloAkka-
akka.actor.default-dispatcher-4]
[akka://HelloAkka/user/shutdownActor2] Message
[java.lang.String] from Actor[akka://HelloAkka/deadLetters]
to Actor[akka://HelloAkka/user/shutdownActor2#788021817] was
not delivered. [2] dead letters encountered.

How it works...

In step three, we create a Stop message. Upon receiving this message, the actor will stop using context.stop(self).

In step four, we define an actor which handles the Stop message.

In step five, we create two actors of the same class, shutdownActor1 and shutdownActor2. We shut down shutdownActor1 using PoisonPill and shutdownActor2 using context.stop(self).

PoisonPill and context.stop(self) are the two ways to kill an actor. PoisonPill is the inbuilt message that is handled after all the messages that were already queued in the mailbox.

Context.stop is basically used for an ordered shutdown of actors when you want the child actors to stop first, then the parent actor, followed by the ActorSystem to stop top-level actors.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Covers a discussion on Lagom—the newest launched Akka framework that is built to create complex microservices easily
  • The recipe approach of the book allows the reader to know important and independent concepts of Scala and Akka in a seamless manner
  • Provides a comprehensive understanding of the Akka actor model and implementing it to create reactive web applications

Description

Akka is an open source toolkit that simplifies the construction of distributed and concurrent applications on the JVM. This book will teach you how to develop reactive applications in Scala using the Akka framework. This book will show you how to build concurrent, scalable, and reactive applications in Akka. You will see how to create high performance applications, extend applications, build microservices with Lagom, and more. We will explore Akka's actor model and show you how to incorporate concurrency into your applications. The book puts a special emphasis on performance improvement and how to make an application available for users. We also make a special mention of message routing and construction. By the end of this book, you will be able to create a high-performing Scala application using the Akka framework.

Who is this book for?

If you are a Scala developer who wants to build scalable and concurrent applications, then this book is for you. Basic knowledge of Akka will help you take advantage of this book.

What you will learn

  • Control an actor using the ContolAware mailbox
  • Test a fault-tolerant application using the Akka test kit
  • Create a parallel application using futures and agents
  • Package and deploy Akka application inside Docker
  • Deploy remote actors programmatically on different nodes
  • Integrate Streams with Akka actors
  • Install Lagom and create a Lagom project
Estimated delivery fee Deliver to Malta

Premium delivery 7 - 10 business days

€32.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : May 26, 2017
Length: 414 pages
Edition : 1st
Language : English
ISBN-13 : 9781785288180
Category :
Languages :
Concepts :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to Malta

Premium delivery 7 - 10 business days

€32.95
(Includes tracking information)

Product Details

Publication date : May 26, 2017
Length: 414 pages
Edition : 1st
Language : English
ISBN-13 : 9781785288180
Category :
Languages :
Concepts :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 120.97
Learning Concurrent Programming in Scala
€36.99
Mastering Akka
€41.99
Akka Cookbook
€41.99
Total 120.97 Stars icon
Banner background image

Table of Contents

11 Chapters
Diving into Akka Chevron down icon Chevron up icon
Supervision and Monitoring Chevron down icon Chevron up icon
Routing Messages Chevron down icon Chevron up icon
Using Futures and Agents Chevron down icon Chevron up icon
Scheduling Actors and Other Utilities Chevron down icon Chevron up icon
Akka Persistence Chevron down icon Chevron up icon
Remoting and Akka Clustering Chevron down icon Chevron up icon
Akka Streams Chevron down icon Chevron up icon
Akka HTTP Chevron down icon Chevron up icon
Understanding Various Akka patterns Chevron down icon Chevron up icon
Microservices with Lagom Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.2
(10 Ratings)
5 star 70%
4 star 0%
3 star 10%
2 star 20%
1 star 0%
Filter icon Filter
Top Reviews

Filter reviews by




Amazon Customer Aug 08, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I have been using Akka for a while now. I've found this book to cover most of my use cases, plus some that I've not encountered yet. The example code is quite clear. I really like the "cookbook" format and would like to see it continue into advance scenarios.
Amazon Verified review Amazon
Amazon Customer Aug 10, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Great book! I was starting from zero with Akka and in no time I was able to implement the use case I wanted following several recipes. Totally recommended!
Amazon Verified review Amazon
Amazon Customer Jun 11, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I learnt a lot with this book. Useful and great attention to details. Code examples are helpful.
Amazon Verified review Amazon
kokalos Nov 05, 2020
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Il panorama della programmazione ad attori è abbastanza vasto. Questo libro ha il pregio di trattare in modo incrementale tutti gli aspetti del framework dalla applicazione semplice fino ai micro servizi
Amazon Verified review Amazon
Seth Kong Sep 24, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I find this book very helpful in applying Akka in my projects. I was reading many books on Akka before but this book is taking me to the next level. If you are looking to build the strong foundation with Akka using Scala this book is for you.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela