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:
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:
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:
# 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:
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.
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:
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: