title: AKKA Shutdown Pattern doesn't work
body: <p>After I read this excellent blog written by the AKKA team, <a href="http://letitcrash.com/post/30165507578/shutdown-patterns-in-akka-2" rel="nofollow noreferrer">Shutdown Patterns in AKKA 2</a>, I run the code and it indeed works.</p>
  <p>But when I do another experiment with a slight change, throwing out an exception in workers, then this pattern won't work. Since it's reasonable that workers may throw any kinds of exceptions during working, right?</p>
  <p>The following are my code, two files:</p>
  <p>Reaper.scala, copied from the article mentioned above:</p>
  <pre><code>import akka.actor.{Actor, ActorRef, Terminated}
  import scala.collection.mutable.ArrayBuffer
  
  object Reaper {
    // Used by others to register an Actor for watching
    case class WatchMe(ref: ActorRef)
  }
  
  abstract class Reaper extends Actor {
    import Reaper._
  
    // Keep track of what we're watching
    val watched = ArrayBuffer.empty[ActorRef]
  
    // Derivations need to implement this method.  It's the
    // hook that's called when everything's dead
    def allSoulsReaped(): Unit
  
    // Watch and check for termination
    final def receive = {
      case WatchMe(ref) =&gt;
        context.watch(ref)
        watched += ref
      case Terminated(ref) =&gt;
        watched -= ref
        if (watched.isEmpty) allSoulsReaped()
    }
  }
  </code></pre>
  <p>TestWorker.scala</p>
  <pre><code>import akka.actor.{SupervisorStrategy, Props, ActorSystem, Actor}
  import Reaper._
  
  
  class TestReaper extends Reaper {
    def allSoulsReaped(): Unit = context.system.shutdown()
    override val supervisorStrategy = SupervisorStrategy.stoppingStrategy
  }
  
  // The reaper sends this message to all workers to notify them to start work
  case object StartWork
  
  class TestWorker extends  Actor {
    def receive = {
      case StartWork =&gt;
        // do real work ...
        throw new IllegalStateException(&quot;Simulate uncaught exceptions during work&quot;)
    }
  }
  
  object TestWorker {
    def main(args: Array[String]) : Unit = {
      val system = ActorSystem(&quot;system&quot;)
      val reaper = system.actorOf(Props[TestReaper])
      val worker1 = system.actorOf(Props[TestWorker])
      val worker2 = system.actorOf(Props[TestWorker])
  
      reaper ! WatchMe(worker1)
      reaper ! WatchMe(worker2)
      Thread.sleep(3000) // make sure WatchMe will be delivered before StartWork
      worker1 ! StartWork
      worker2 ! StartWork
      system.awaitTermination()
    }
  }
  </code></pre>
  <p>This program will hang forever.</p>
  <p>It seems the reaper cannot receive <code>Terminated</code> messages if workers throw uncaught exceptions</p>
  <p>Can somebody tell my why? Many thanks in advance!</p>
  <p><strong>Correct answer</strong> by @mattinbits:</p>
  <p>The reason that this program hangs forever is that in my code <code>TestWorker</code> are not children of <code>TestReaper</code> even <code>TestReaper</code> calls  <code>context.watch(ref)</code>.</p>
  <p><strong>context.watch() doesn't mean becoming a child.</strong> <code>context.watch(ref)</code> just means that <code>TestReaper</code> will get notified when a <code>TestWorker</code> actor dies.</p>
  <p><code>SupervisorStrategy</code> and <code>context.watch()</code> are two different things. <code>SupervisorStrategy</code> will only have influence on all children actors.</p>
  <p>Putting  <code>override val supervisorStrategy = SupervisorStrategy.stoppingStrategy</code> in the <code>TestReaper</code> won't make <code>TestWorker</code> stopped when exceptions happen inside <code>TestWorker</code>.  Instead we need to change the <code>SupervisorStrategy</code> of  <code>TestWorker</code>s parent actor. Since all actors in the code above are created by <code>system.actorOf()</code>, they are children of the <a href="http://doc.akka.io/docs/akka/snapshot/general/supervision.html#_user__The_Guardian_Actor" rel="nofollow noreferrer">Guardian Actor <code>/user</code></a>, so actually we need to change the supervision strategy of the <code>/user</code> actor , by adding <code>akka { actor { guardian-supervisor-strategy = &quot;akka.actor.StoppingSupervisorStrategy&quot; } }</code> in <code>application.conf</code></p>
  <p>However, it's better to use another actor as the supervision actor, just like what @mattinbits does in his code.</p>