I suggest adding the dispatcher configuration to the current PoolRouter DSL.
I need a pool router to spawn its children with a specific dispatcher, because they perform CPU-heavy computation and should not use the default dispatcher. This is not possible in the current Akka Typed DSL.
I would like to be able to control the used dispatchers explicitly. I could imagine the following extensions of the Pool Router DSL. Other suggestions welcome!
```scala
def heavyLoad: Behavior[Command] = Behaviors.receive{ case (ctx, _: Command) =>
// heavy CPU load for ~1-2s
Behaviors.same
}
val n = _ // max number of cores
val pool: PoolRouter[Command] = Routers
.pool(n)(
Behaviors.supervise(heavyLoad).onFailure(
SupervisorStrategy.restart.withLimit(3, 8 seconds)
)
)
.withRoundRobinRouting()
// 1) my favorable suggestion:
// builder methods with parameter type: akka.actor.typed.DispatcherSelector
.withHeadDispatcher(DispatcherSelector.default())
.withRouteeDispatcher(DispatcherSelector.fromConfig("cpu-bound-dispatcher"))
// 2) or maybe use the more general props wording:
// parameter type: akka.actor.typed.Props
.withProps(DispatcherSelector.default())
.withRouteeProps(DispatcherSelector.fromConfig("cpu-bound-dispatcher"))
```
Falling back to the more feature-rich Akka classic APIs (not tested like that yet):
val strategy: SupervisorStrategy = OneForOneStrategy() {
case _ => SupervisorStrategy.Restart
}
val router: Props = RoundRobinPool(
nrOfInstances = n,
supervisorStrategy = strategy,
routerDispatcher = Dispatchers.DefaultDispatcherId
).props(
routeeProps = Props[HeavyLoadWorker].withDispatcher("cpu-bound-dispatcher")
)
I would like to circumvent this, because I would have to make my workers classic actors and the new typed APIs are nicer :smiley:
Unfortunately, I can not use the Group Router, because the code is performance critical and I do not want to send the tasks to all workers across nodes (I also use Akka Cluster Typed), although it supports spawning workers with props.
Do you have any other ideas how to achieve this?
I would be glad to help shaping this idea or submitting a PR with the necessary changes.
.withRouteeProps(props) sounds like the right way to do it to me, a PR adding that would be great.
Ok. I will create a PR for it.
My plan is to add the new withRouteeProps(props) to the builder and then change the PoolRouterImpl from:
to:
private final class PoolRouterImpl[T](
ctx: ActorContext[T],
poolSize: Int,
behavior: Behavior[T],
logic: RoutingLogic[T],
routeeProps: Option[Props])
extends AbstractBehavior[T](ctx) {
This means that the default behavior would be the same, and only if one supplies routeeProps, they will be used to spawn the routees.
You can skip having an Option and always have a props and use Props.empty as starting value.