Search code examples
scalaakkaactor

How to terminate a hung akka actor?


I'm writing my HelloWorld for Akka, I have fixed (20 to 50) number of actors created in a Main Actor, half of them are simple counters, another half calculates factorial and sums results in some way. The main goal was to test how Akka handles naughty hung threads. I added Thread.sleeps with semi-random time to my threads and defined a timeout by scheduling special ForceShutdown case.

What I wanted to get:

  • 1) Main Actor receives StopMessage, collects results from child-actors and gives them the PoisonPill
  • 2) Once all the results are collected, main Actor shuts down the system
  • 3) If the results are not collected during the timeout, a ForceShutdown case is firing up, killing everything and shuts down the system by force.

What I got: 1 and 2 are working right, but:

  • 3) Once ForceShutdown is fired, MainActor is still waiting for children to finish their work, it doesn't terminate them.

I tried several variants of ForceShutdown case, but most of them work just the same, waiting for the child actor to finish unfinished work. Here's an example:

case ForceShutdown =>
  println(s"[${self.path.name}] ForceShutdown received!")
  children foreach { child => system.stop(child) }
  system shutdown

So, how to force terminate hung actors in Akka?


Solution

  • On the JVM there is no way to forcefully shut anything down, since terminating something within the same process will likely corrupt shared state and lead to a broken application. Your idea with the Future will appear to work at first, but the thread pool that runs your runaway code will not shut down, meaning that the JVM will not stop or will accumulate defunct thread pools and eventually run out of memory.

    As a consequence you should design all your actors to stay responsive: if you need to run long processing tasks you should break them up into short steps that the actor sends to itself. That way a termination request will be honored in due time.