I want to have fixed thread pool with once created threads. So, I create own ExecutorServiceConfigurator
:
class FixedThreadPoolExecutorServiceConfigurator(config: Config, prerequisites: DispatcherPrerequisites) extends ExecutorServiceConfigurator(config, prerequisites) {
class ThreadPoolExecutorServiceFactory extends ExecutorServiceFactory {
def createExecutorService: ExecutorService = {
Executors.newFixedThreadPool(40)
}
}
private val executor = new ThreadPoolExecutorServiceFactory()
override def createExecutorServiceFactory(id: String, threadFactory: ThreadFactory): ExecutorServiceFactory = {
executor
}
}
And used it:
blocking-dispatcher {
type = Dispatcher
executor = "abc.FixedThreadPoolExecutorServiceConfigurator"
throughput = 1
thread-pool-executor {
fixed-pool-size = 60
}
}
But every time, when my program has no any tasks, Akka shutdowns ExecutorService:
akka.dispatch.MessageDispatcher:
private val shutdownAction = new Runnable {
@tailrec
final def run(): Unit = {
shutdownSchedule match {
case SCHEDULED ⇒
try {
if (inhabitants == 0) shutdown() //Warning, racy
}
//////
}
}
}
I cannot understand this behavior. I think, that creation of threads is expensive operation.
It does not stop the executor when it runs out of tasks. The shutdown is only run when the last actor of that dispatcher is stopped and a timeout has passed (shutdown-timeout
on the dispatcher config) with no new actors assigned to the dispatcher is started.
For a use case with a dispatcher with many short lived actors and periods of no actors running that are > 1 second which is the default you could potentially tune the setting to a much higher value to keep the executor alive.