Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / All-Topics

Akka Mailboxes

5.00/5 (3 votes)
2 Aug 2016CPOL3 min read 8.8K  
Akka Mailboxes

This post will be a bit smaller than the ones we have just done, but none the less, still just as important.

Let’ start by talking about mailboxes and dispatchers, and what exactly they are and how they relate to each other.

What’s A Mailbox?

In Akka, the mailbox is some time of queue that holds the messages for an actor. There is usually a mailbox per actor. Though in some cases, where routing gets involved there may only be one mailbox between a number of actors, but for now lets assume a one to one relationship between mailboxes and actors.

What’s A Dispatcher

In Akka, a Dispatcher is the heart of the actor system, and it is the thing that dispatches the messages.

There is a way that Akka actors may be configured to use a certain Dispatcher and the Dispatcher may in turn be configured to use a certain mailbox type.

Here is an example of how you might configure an actor to use a custom Dispatcher.

You may have this code for an actor:

Scala
import akka.actor.Props
val myActor =
  context.actorOf(Props[MyActor].withDispatcher("my-dispatcher"), "myactor1")

Where you may have this custom Dispatcher in your configuration of the system:

Scala
my-dispatcher {
 
  # Type of mailbox to use for the Dispatcher
  mailbox-requirement = org.example.MyInterface
 
  # Dispatcher is the name of the event-based dispatcher
  type = Dispatcher
 
  # What kind of ExecutionService to use
  executor = "thread-pool-executor"
 
  # Configuration for the thread pool
  thread-pool-executor {
 
    # minimum number of threads to cap factor-based core number to
    core-pool-size-min = 2
 
    # No of core threads ... ceil(available processors * factor)
    core-pool-size-factor = 2.0
 
    # maximum number of threads to cap factor-based number to
    core-pool-size-max = 10
  }
 
  # Throughput defines the maximum number of messages to be
  # processed per actor before the thread jumps to the next actor.
  # Set to 1 for as fair as possible.
  throughput = 100
}

It can be seen above that we are able to configure the mailbox type for a Dispatcher in the configuration using the line:

Scala
# Type of mailbox to use for the Dispatcher
mailbox-requirement = org.example.MyInterface    

There are actually several inbuilt Dispatcher types that you may use when creating a custom Dispatcher.

Talking about Dispatch types and how they all work is kind of out of scope for what I wanted to talk about in this post though, so if you want to know more about Akka Dispatchers, you should consult the official Akka documentation:

Ok, so now that we have taken that slight detour and talked about how you can associate a mailbox type with a custom Dispatcher should you want to, let’s get back to the main thrust of this post, which is to talk about mailboxes.

As previously stated, mailboxes represent a storage mechanism for an actors messages.

Built In Mailbox Types

Akka comes shipped with a number of mailbox implementations:

UnboundedMailbox – The Default Mailbox

  • Backed by a java.util.concurrent.ConcurrentLinkedQueue
  • Blocking: No
  • Bounded: No
  • Configuration name: “unbounded” or “akka.dispatch.UnboundedMailbox

SingleConsumerOnlyUnboundedMailbox

  • Backed by a very efficient Multiple Producer Single Consumer queue, cannot be used with
  • BalancingDispatcher
  • Blocking: No
  • Bounded: No
  • Configuration name: “akka.dispatch.SingleConsumerOnlyUnboundedMailbox

BoundedMailbox

  • Backed by a java.util.concurrent.LinkedBlockingQueue
  • Blocking: Yes
  • Bounded: Yes
  • Configuration name: “bounded” or “akka.dispatch.BoundedMailbox

UnboundedPriorityMailbox

  • Backed by a java.util.concurrent.PriorityBlockingQueue
  • Blocking: Yes
  • Bounded: No
  • Configuration name: “akka.dispatch.UnboundedPriorityMailbox

BoundedPriorityMailbox

  • Backed by a java.util.PriorityBlockingQueue wrapped in an akka.util.BoundedBlockingQueue
  • Blocking: Yes
  • Bounded: Yes
  • Configuration name: “akka.dispatch.BoundedPriorityMailbox

Default Mailbox

As shown above, the unbounded mailbox is the default. You can however swap out the default using the following configuration, though you will need to ensure that the chosen default mailbox is the correct one for the type of Dispatcher used. For example, a SingleConsumerOnlyUnboundedMailbox cannot be used with a BalancingDispatcher.

Anyway, this is how you would change the default mailbox in config:

Scala
akka.actor.default-mailbox {
  mailbox-type = "akka.dispatch.SingleConsumerOnlyUnboundedMailbox"
}

Mailbox Type For An Actor

It is possible to associate a particular type of mailbox with a particular type of an actor which can be done by mixing in the RequiresMessageQueue trait.

Scala
import akka.dispatch.RequiresMessageQueue
import akka.dispatch.BoundedMessageQueueSemantics
  
class SomeActor extends Actor
  with RequiresMessageQueue[BoundedMessageQueueSemantics]   

Where you would use the following configuration to configure the mailbox:

Scala
bounded-mailbox {
  mailbox-type = "akka.dispatch.BoundedMailbox"
  mailbox-capacity = 1000
  mailbox-push-timeout-time = 10s
}
  
akka.actor.mailbox.requirements {
  "akka.dispatch.BoundedMessageQueueSemantics" = bounded-mailbox
}

It is worth noting that this setting could be overwritten by code or by a dispatcher mailbox configuration section.

Where Is The Code?

As previously stated all the code for this series will end up in this GitHub repo:

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)