diff --git a/akka-actor-tests/src/test/scala/akka/actor/Supervisor.scala b/akka-actor-tests/src/test/scala/akka/actor/Supervisor.scala index a956c2d090..174939915d 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/Supervisor.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/Supervisor.scala @@ -7,5 +7,6 @@ class Supervisor extends Actor { def receive = { case x: Props ⇒ sender ! context.actorOf(x) } + // need to override the default of stopping all children upon restart, tests rely on keeping them around override def preRestart(cause: Throwable, msg: Option[Any]) {} } diff --git a/akka-actor-tests/src/test/scala/akka/actor/SupervisorHierarchySpec.scala b/akka-actor-tests/src/test/scala/akka/actor/SupervisorHierarchySpec.scala index 3b9ebbad73..d51b333b35 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/SupervisorHierarchySpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/SupervisorHierarchySpec.scala @@ -15,6 +15,7 @@ object SupervisorHierarchySpec { protected def receive = { case p: Props ⇒ sender ! context.actorOf(p) } + // test relies on keeping children around during restart override def preRestart(cause: Throwable, msg: Option[Any]) {} override def postRestart(reason: Throwable) = { countDown.countDown() diff --git a/akka-actor/src/main/resources/reference.conf b/akka-actor/src/main/resources/reference.conf index 465e5c171b..3a8acb7ca7 100644 --- a/akka-actor/src/main/resources/reference.conf +++ b/akka-actor/src/main/resources/reference.conf @@ -37,7 +37,7 @@ akka { actor { provider = "akka.actor.LocalActorRefProvider" creation-timeout = 20s # Timeout for ActorSystem.actorOf - reaper-period = 5s # frequency with which stopping actors are prodded in case they had to be removed from their parents + reaper-interval = 5s # frequency with which stopping actors are prodded in case they had to be removed from their parents timeout = 5s # Default timeout for Future based invocations # - Actor: ask && ? # - UntypedActor: ask diff --git a/akka-actor/src/main/scala/akka/actor/ActorCell.scala b/akka-actor/src/main/scala/akka/actor/ActorCell.scala index 74bd482162..be6bf2d1f4 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorCell.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorCell.scala @@ -185,7 +185,7 @@ private[akka] class ActorCell( val system: ActorSystemImpl, val self: InternalActorRef, val props: Props, - final val parent: InternalActorRef, + @volatile var parent: InternalActorRef, /*no member*/ _receiveTimeout: Option[Duration], var hotswap: Stack[PartialFunction[Any, Unit]]) extends UntypedActorContext { diff --git a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala index 01cde0720c..a07b14ac43 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala @@ -240,6 +240,10 @@ trait ActorRefFactory { * an asynchronous operation, i.e. involves a message send, but if invoked * on an [[akka.actor.ActorContext]] if operating on a child of that * context it will free up the name for immediate reuse. + * + * When invoked on [[akka.actor.ActorSystem]] for a top-level actor, this + * method sends a message to the guardian actor and blocks waiting for a reply, + * see `akka.actor.creation-timeout` in the `reference.conf`. */ def stop(actor: ActorRef): Unit } diff --git a/akka-actor/src/main/scala/akka/actor/ActorSystem.scala b/akka-actor/src/main/scala/akka/actor/ActorSystem.scala index f801f7120d..0ce6b4d529 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorSystem.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorSystem.scala @@ -73,7 +73,7 @@ object ActorSystem { val ProviderClass = getString("akka.actor.provider") val CreationTimeout = Timeout(Duration(getMilliseconds("akka.actor.creation-timeout"), MILLISECONDS)) - val ReaperPeriod = Duration(getMilliseconds("akka.actor.reaper-period"), MILLISECONDS) + val ReaperInterval = Duration(getMilliseconds("akka.actor.reaper-interval"), MILLISECONDS) val ActorTimeout = Timeout(Duration(getMilliseconds("akka.actor.timeout"), MILLISECONDS)) val SerializeAllMessages = getBoolean("akka.actor.serialize-messages") @@ -441,7 +441,7 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor this } - lazy val locker: Locker = new Locker(scheduler, ReaperPeriod, lookupRoot.path / "locker", deathWatch) + lazy val locker: Locker = new Locker(scheduler, ReaperInterval, lookupRoot.path / "locker", deathWatch) def start() = _start diff --git a/akka-actor/src/main/scala/akka/actor/Locker.scala b/akka-actor/src/main/scala/akka/actor/Locker.scala index f9c9546f2b..8bbcdd15e6 100644 --- a/akka-actor/src/main/scala/akka/actor/Locker.scala +++ b/akka-actor/src/main/scala/akka/actor/Locker.scala @@ -15,7 +15,7 @@ class Locker(scheduler: Scheduler, period: Duration, val path: ActorPath, val de def run = { val iter = heap.entrySet.iterator while (iter.hasNext) { - val soul = iter.next(); + val soul = iter.next() deathWatch.subscribe(Locker.this, soul.getKey) // in case Terminated got lost somewhere soul.getKey match { case _: LocalActorRef ⇒ // nothing to do, they know what they signed up for @@ -41,24 +41,10 @@ class Locker(scheduler: Scheduler, period: Duration, val path: ActorPath, val de soul match { case local: LocalActorRef ⇒ val cell = local.underlying - rebind(cell, cell.getClass) + cell.parent = this case _ ⇒ } case _ ⇒ // ignore } - @scala.annotation.tailrec - final private def rebind(cell: ActorCell, clazz: Class[_]): Unit = { - try { - val heart = clazz.getDeclaredField("parent") - heart.setAccessible(true) - heart.set(cell, this) - return - } catch { - case _: NoSuchFieldException ⇒ - } - val sc = clazz.getSuperclass - if (sc != null) rebind(cell, sc) - } - } diff --git a/akka-actor/src/main/scala/akka/actor/UntypedActor.scala b/akka-actor/src/main/scala/akka/actor/UntypedActor.scala index 13677f84cc..ccac32f82f 100644 --- a/akka-actor/src/main/scala/akka/actor/UntypedActor.scala +++ b/akka-actor/src/main/scala/akka/actor/UntypedActor.scala @@ -27,7 +27,7 @@ import akka.dispatch.{ MessageDispatcher, Promise } * * {{{ * public class SampleUntypedActor extends UntypedActor { - * + * * public class Reply { * final public ActorRef sender; * final public Result result; @@ -36,7 +36,7 @@ import akka.dispatch.{ MessageDispatcher, Promise } * this.result = result; * } * } - * + * * public void onReceive(Object message) throws Exception { * if (message instanceof String) { * String msg = (String)message;