3
votes

I have a few database IO operations I would like to run concurrently. In my case it would be best to use a BalancingPool Router.

The docs say if blocking operations are to occur in the workers then one should use a thread-pool-executor rather than the default fork-join-dispatcher.

I did not want to configure it in the Akka conf file so I think this would be the way to do it in code:

  val router = context.actorOf(BalancingPool(5).withDispatcher("my-pinned-dispatcher").props(Props[History]), "HistoryBalancingRouter")

But the docs say for a PinnedDispatcher:

This dispatcher dedicates a unique thread for each actor using it; i.e. each actor will have its own thread pool with only one thread in the pool.

Mailboxes: Any, creates one per Actor

Whereas for the BalancingPool it says workers share a single mailbox:

The BalancingPool automatically uses a special BalancingDispatcher for its routees - disregarding any dispatcher that is set on the 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. 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

So what is actually happening with mailboxes and threads here?

Is my example a sane way to implement a BalancingPool using a thread-pool-executor?

1

1 Answers

2
votes

The BalancingPool always works with a BalancingDispatcher, it will simply refuse your PinnedDispatcher setting. The reason is exactly that the BalancingDispatcher allows actors to share a common mailbox (for performance) which other Dispatchers do not support.

Please note that several of the Dispatchers allow you to configure the Executor that they will use inside. By default, for BalancingPool it is the fork-join-executor (the docs incorrectly say "fork-join-dispatcher") but you can change it to use a thread-pool-executor. An example dispatcher configuration is here: http://doc.akka.io/docs/akka/2.3.13/scala/dispatchers.html#Setting_the_dispatcher_for_an_Actor you just need to change the executor type