Announcing Akka 24.05: More Security. More Performance. More Efficiency. Watch the Webinar Replay

Akka: One Dispatcher to Rule Them All

by Viktor Klang

In this post I'll talk about the updated dispatcher strategy that is new with Akka 1.1.

For those of you who don't know what an Akka Dispatcher is - it's the engine of Akka, the thing that makes it tick, the thing that makes sure that the available CPU resources are optimally divided between the things that needs to be executed. In other words, it's at the heart of Akka's concurrency model.

Here's what is new in Dispatchers with Akka 1.1:

  1. All Dispatchers in Akka core are now built on top of the ExecutorBasedEventDrivenDispatcher, which is a very versatile and high-performance dispatcher implementation. This means that any performance improvements that are made in that will cascade to all the others.
  2. A ThreadBasedDispatcher is a dispatcher that only has one Thread in its thread pool, and every ThreadBasedDispatcher can only be used by one actor instance. This ensures that the actor will not be CPU starved by other actors. Also, it will deallocate its thread after a specified timeout, and will require it when needed, so as not to hog scarce resources.
  3. The ExecutorBasedWorkStealingDispatcher now redistributes work to actors that use the same dispatcher and that do not currently have any messages the mailbox.
  4. HawtDispatcher has been moved to a compatibility JAR in Akka modules, for those who want to keep using it. Worth noting is that the ExecutorBasedEventDrivenDispatcher is more performant and way more tunable, and HawtDispatcher does not support some of the methods in the MessageDispatcher contract, like getMailboxSize.
  5. There is a new dispatcher, called PriorityExecutorBasedEventDrivenDispatcher, that allows you to supply it with a Comparator that will determine the processing order of messages sent to actors that use this dispatcher.
  6. As a consequence of having all dispatchers in akka-actor use the same base, they all support the same basic configuration options.
  7. You can now write your own dispatcher, or extend any of the built-in ones, and be able to configure it from the Akka configuration file, by creating a class that extends MessageDispatcherConfigurator and then in the conf file, instead of
    type = "GlobalExecutorBasedEventDriven"
    or similar, you enter
    type = "my.own.dispatcher.configurator.FQN"
    And then Akka will load your dispatcher configurator and will use that to create the dispatcher instance.
  8. Dispatchers can now be used to execute blocks of code that will compute the result of a Future, which is very low in overhead.
    object Future {
       * This method constructs and returns a Future that will eventually hold the result of the execution of the supplied body
       * The execution is performed by the specified Dispatcher.
      def apply[T](body: => T, timeout: Long = Actor.TIMEOUT)(implicit dispatcher: MessageDispatcher): Future[T]
    Scala example:
    val f = Future(someThunk)/*(someDispatcher)*/
    Java example:
    import static akka.dispatch.Futures.future;
    Future f = future(someCallableThatReturnsInteger/*, someDispatcher*/);
  9. There has been a lot of effort made to optimize the ExecutorBasedEventDrivenDispatcher, so just by upgrading to Akka 1.1 you'll get an extra performance boost versus previous versions.

To sum things up: Faster, stronger, smaller, and more flexible.  One dispatcher to rule them all.

The Total Economic Impact™
Of Lightbend Akka

  • 139% ROI
  • 50% to 75% faster time-to-market
  • 20x increase in developer throughput
  • <6 months Akka pays for itself