Classic Dispatchers

Note

Akka Classic pertains to the original Actor APIs, which have been improved by more type safe and guided Actor APIs. Akka Classic is still fully supported and existing applications can continue to use the classic APIs. It is also possible to use the new Actor APIs together with classic actors in the same ActorSystem, see coexistence. For new projects we recommend using the new Actor API.

For the full documentation of this feature and for new projects see Dispatchers.

Dependency

The Akka dependencies are available from Akka’s library repository. To access them there, you need to configure the URL for this repository.

sbt
resolvers += "Akka library repository".at("https://repo.akka.io/maven")
Maven
<project>
  ...
  <repositories>
    <repository>
      <id>akka-repository</id>
      <name>Akka library repository</name>
      <url>https://repo.akka.io/maven</url>
    </repository>
  </repositories>
</project>
Gradle
repositories {
    mavenCentral()
    maven {
        url "https://repo.akka.io/maven"
    }
}

Dispatchers are part of core Akka, which means that they are part of the akka-actor dependency:

sbt
val AkkaVersion = "2.10.0+31-e778606c-SNAPSHOT"
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % AkkaVersion
Maven
<properties>
  <scala.binary.version>2.13</scala.binary.version>
</properties>
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.typesafe.akka</groupId>
      <artifactId>akka-bom_${scala.binary.version}</artifactId>
      <version>2.10.0+31-e778606c-SNAPSHOT</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
<dependencies>
  <dependency>
    <groupId>com.typesafe.akka</groupId>
    <artifactId>akka-actor_${scala.binary.version}</artifactId>
  </dependency>
</dependencies>
Gradle
def versions = [
  ScalaBinary: "2.13"
]
dependencies {
  implementation platform("com.typesafe.akka:akka-bom_${versions.ScalaBinary}:2.10.0+31-e778606c-SNAPSHOT")

  implementation "com.typesafe.akka:akka-actor_${versions.ScalaBinary}"
}

Looking up a Dispatcher

Dispatchers implement the ExecutionContextExecutor interface and can thus be used to run FutureCompletableFuture invocations etc.

Scala
source// for use with Futures, Scheduler, etc.
implicit val executionContext = system.dispatchers.lookup("my-dispatcher")
Java
source// this is scala.concurrent.ExecutionContextExecutor, which implements
// both scala.concurrent.ExecutionContext (for use with Futures, Scheduler, etc.)
// and java.util.concurrent.Executor (for use with CompletableFuture etc.)
final ExecutionContextExecutor ex = system.dispatchers().lookup("my-dispatcher");

Setting the dispatcher for an Actor

So in case you want to give your ActorActor a different dispatcher than the default, you need to do two things, of which the first is to configure the dispatcher:

sourcemy-dispatcher {
  # Dispatcher is the name of the event-based dispatcher
  type = Dispatcher
  # What kind of ExecutionService to use
  executor = "fork-join-executor"
  # Configuration for the fork join pool
  fork-join-executor {
    # Min number of threads to cap factor-based parallelism number to
    parallelism-min = 2
    # Parallelism (threads) ... ceil(available processors * factor)
    parallelism-factor = 2.0
    # Max number of threads to cap factor-based parallelism number to
    parallelism-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
}
Note

Note that the parallelism-max does not set the upper bound on the total number of threads allocated by the ForkJoinPool. It is a setting specifically talking about the number of hot threads the pool keep running in order to reduce the latency of handling a new incoming task. You can read more about parallelism in the JDK’s ForkJoinPool documentation.

Another example that uses the “thread-pool-executor”:

sourceblocking-io-dispatcher {
  type = Dispatcher
  executor = "thread-pool-executor"
  thread-pool-executor {
    fixed-pool-size = 32
  }
  throughput = 1
}
Note

The thread pool executor dispatcher is implemented using a java.util.concurrent.ThreadPoolExecutor. You can read more about it in the JDK’s ThreadPoolExecutor documentation.

For more options, see Dispatchers and the default-dispatcher section of the configuration.

Then you create the actor as usual and define the dispatcher in the deployment configuration.

Scala
sourceimport akka.actor.Props
val myActor = context.actorOf(Props[MyActor](), "myactor")
Java
sourceActorRef myActor = system.actorOf(Props.create(MyActor.class), "myactor");
sourceakka.actor.deployment {
  /myactor {
    dispatcher = my-dispatcher
  }
}

An alternative to the deployment configuration is to define the dispatcher in code. If you define the dispatcher in the deployment configuration then this value will be used instead of programmatically provided parameter.

Scala
sourceimport akka.actor.Props
val myActor =
  context.actorOf(Props[MyActor]().withDispatcher("my-dispatcher"), "myactor1")
Java
sourceActorRef myActor =
    system.actorOf(Props.create(MyActor.class).withDispatcher("my-dispatcher"), "myactor3");
Note

The dispatcher you specify in withDispatcherwithDispatcher and the dispatcher property in the deployment configuration is in fact a path into your configuration. So in this example it’s a top-level section, but you could for instance put it as a sub-section, where you’d use periods to denote sub-sections, like this: "foo.bar.my-dispatcher"

Found an error in this documentation? The source code for this page can be found here. Please feel free to edit and contribute a pull request.