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 6c438f1776..a956c2d090 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/Supervisor.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/Supervisor.scala @@ -7,4 +7,5 @@ class Supervisor extends Actor { def receive = { case x: Props ⇒ sender ! context.actorOf(x) } + 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 dc45d012fd..3b9ebbad73 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) } + override def preRestart(cause: Throwable, msg: Option[Any]) {} override def postRestart(reason: Throwable) = { countDown.countDown() } diff --git a/akka-actor/src/main/scala/akka/actor/Actor.scala b/akka-actor/src/main/scala/akka/actor/Actor.scala index ffb941408a..4c8877463c 100644 --- a/akka-actor/src/main/scala/akka/actor/Actor.scala +++ b/akka-actor/src/main/scala/akka/actor/Actor.scala @@ -262,9 +262,12 @@ trait Actor { *
* Is called on a crashed Actor right BEFORE it is restarted to allow clean * up of resources before Actor is terminated. - * By default it calls postStop() + * By default it disposes of all children calls postStop(). */ - def preRestart(reason: Throwable, message: Option[Any]) { postStop() } + def preRestart(reason: Throwable, message: Option[Any]) { + context.children foreach (context.stop(_)) + postStop() + } /** * User overridable callback. diff --git a/akka-docs/general/supervision.rst b/akka-docs/general/supervision.rst index 0867d931f8..74c95abfc5 100644 --- a/akka-docs/general/supervision.rst +++ b/akka-docs/general/supervision.rst @@ -25,7 +25,9 @@ which explains the existence of the fourth choice (as a supervisor also is subordinate to another supervisor higher up) and has implications on the first three: resuming an actor resumes all its subordinates, restarting an actor entails restarting all its subordinates, similarly stopping an actor will also -stop all its subordinates. +stop all its subordinates. It should be noted that the default behavior of an +actor is to stop all its children before restarting, but this can be overridden +using the :meth:`preRestart` hook. Each supervisor is configured with a function translating all possible failure causes (i.e. exceptions) into one of the four choices given above; notably, @@ -69,14 +71,12 @@ that the restart is not visible outside of the actor itself with the notable exception that the message during which the failure occurred is not re-processed. -Restarting an actor in this way recursively restarts all its children in the -same fashion, whereby all parent–child relationships are kept intact. If this -is not the right approach for certain sub-trees of the supervision hierarchy, -you should choose to stop the failed actor instead, which will terminate all -its children recursively, after which that part of the system may be recreated -from scratch. The second part of this action may be implemented using the -lifecycle monitoring described next or using lifecycle callbacks as described -in :class:`Actor`. +Restarting an actor in this way recursively terminates all its children. If +this is not the right approach for certain sub-trees of the supervision +hierarchy, you may choose to retain the children, in which case they will be +recursively restarted in the same fashion as the failed parent (with the same +default to terminate children, which must be overridden on a per-actor basis, +see :class:`Actor` for details). What Lifecycle Monitoring Means -------------------------------