scalaakkathreadpoolexecutorserviceakka-dispatcher

Why Akka shutdowns dispatcher, when there is no tasks?


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.


Solution

  • 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.