From 8170b9741fe63a2f147b035939b6a9bbff2e82f2 Mon Sep 17 00:00:00 2001 From: momania Date: Wed, 14 Jul 2010 10:02:07 +0200 Subject: [PATCH] Test #328 --- akka-core/src/main/scala/actor/ActorRef.scala | 3 +- .../test/scala/SupervisorHierarchySpec.scala | 53 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 akka-core/src/test/scala/SupervisorHierarchySpec.scala diff --git a/akka-core/src/main/scala/actor/ActorRef.scala b/akka-core/src/main/scala/actor/ActorRef.scala index 9035f6ad24..8a95548b28 100644 --- a/akka-core/src/main/scala/actor/ActorRef.scala +++ b/akka-core/src/main/scala/actor/ActorRef.scala @@ -1071,7 +1071,8 @@ sealed class LocalActorRef private[akka]( "\n\tto non-empty list of exception classes - can't proceed " + toString) } } else { - _supervisor.foreach(_ ! Exit(dead, reason)) // if 'trapExit' is not defined then pass the Exit on + if (lifeCycle.isEmpty) lifeCycle = Some(LifeCycle(Permanent)) // when passing on make sure we have a lifecycle + _supervisor.foreach(_ ! Exit(this, reason)) // if 'trapExit' is not defined then pass the Exit on } } diff --git a/akka-core/src/test/scala/SupervisorHierarchySpec.scala b/akka-core/src/test/scala/SupervisorHierarchySpec.scala new file mode 100644 index 0000000000..75751e3d58 --- /dev/null +++ b/akka-core/src/test/scala/SupervisorHierarchySpec.scala @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2009-2010 Scalable Solutions AB + */ + +package se.scalablesolutions.akka.actor + +import org.scalatest.junit.JUnitSuite +import org.junit.Test +import java.lang.Throwable +import Actor._ +import se.scalablesolutions.akka.config.OneForOneStrategy +import java.util.concurrent.{TimeUnit, CountDownLatch} + +class SupervisorHierarchySpec extends JUnitSuite { + + @Test + def killWorkerShouldRestartMangerAndOtherWorkers = { + val countDown = new CountDownLatch(4) + + val workerOne = actorOf(new CountDownActor(countDown)) + val workerTwo = actorOf(new CountDownActor(countDown)) + val workerThree = actorOf(new CountDownActor( countDown)) + + val boss = actorOf(new Actor{ + self.trapExit = List(classOf[Throwable]) + self.faultHandler = Some(OneForOneStrategy(5, 1000)) + + protected def receive = { case _ => () } + }).start + + val manager = actorOf(new CountDownActor(countDown)) + boss.startLink(manager) + + manager.startLink(workerOne) + manager.startLink(workerTwo) + manager.startLink(workerThree) + + workerOne ! Exit(workerOne, new RuntimeException("Fire the worker!")) + + // manager + all workers should be restarted by only killing a worker + // manager doesn't trap exits, so boss will restart manager + + assert(countDown.await(4, TimeUnit.SECONDS)) + } + + class CountDownActor(countDown: CountDownLatch) extends Actor { + + protected def receive = { case _ => () } + + override def postRestart(reason: Throwable) = countDown.countDown + } +} +