Akka Balancing Pool with variable-size Thread-Pool-Executor

975 views Asked by At

Here is my use case:

I want to create a Balancing-Pool router of size x (x is the number of instances/routees that is determined at runtime) with each of the routees having its own dedicated thread. Each of the routees is expected to perform blocking operations.

Akka documentation explains that you cannot change the dispatcher of a balancing pool. Which elimintes the option of using a Pinned Dispatcher (which would do exactly what I need, a threadpool of size 1 per routee).

From Akka documentation:

The BalancingPool automatically uses a special BalancingDispatcher for its routees - disregarding any dispatcher that is set on the routee Props object. This is needed in order to implement the balancing semantics via sharing the same mailbox by all the routees.

While it is not possible to change the dispatcher used by the routees, it is possible to fine tune the used executor. By default the fork-join-dispatcher is used and can be configured as explained in Dispatchers [AJ: I believe this is a typo and they mean fork-join-executor]. In situations where the routees are expected to perform blocking operations it may be useful to replace it with a thread-pool-executor hinting the number of allocated threads explicitly

Config sample from Akka docs as well:

akka.actor.deployment {
  /parent/router10b {
    router = balancing-pool
    nr-of-instances = 5
    pool-dispatcher {
      executor = "thread-pool-executor"

      # allocate exactly 5 threads for this pool
      thread-pool-executor {
        core-pool-size-min = 5
        core-pool-size-max = 5
      }
    }
  }
}

It seems like the threadpool executor with a pool size of matching the number of routees would work, but here is the problem: How do I dynamically (at run-time) set the pool size of my threadpool executor to match the number of routees if the pool size has to be set explicitly in the configuration?

Also, is it possible to create the Balancing-Pool (in code) while pulling the executor of its routees from config? i.e. I do not want to use the config to define my router, I want to use:

val myRouter = BalancingPool(x).props(Props[Worker])...)

but somehow specify which executor to use (from config), using the same style of withMailbox() or withDispatcher()

Since the Balancing Dispatcher is "Driven by: java.util.concurrent.ExecutorService", is it possible to create an ExecutorService and pass it to the balancing-pool router or its dispatcher?

1

There are 1 answers

0
Al A On

Perhaps something like this:

val bp = BalancingPool(instances, routerDispatcher = "pinned-dispatcher")
val myRouter = context.actorOf(Props...)
    .withRouter(bp),
  name = "myRouter")