From 9debd392b12912f90a5bdda450225eff0bbf39f0 Mon Sep 17 00:00:00 2001 From: Roland Date: Mon, 20 Feb 2012 21:01:48 +0100 Subject: [PATCH 1/2] remove termination-triggered slaughter, see #1851 --- akka-actor/src/main/scala/akka/actor/FaultHandling.scala | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/akka-actor/src/main/scala/akka/actor/FaultHandling.scala b/akka-actor/src/main/scala/akka/actor/FaultHandling.scala index 6074780801..70246bab30 100644 --- a/akka-actor/src/main/scala/akka/actor/FaultHandling.scala +++ b/akka-actor/src/main/scala/akka/actor/FaultHandling.scala @@ -260,10 +260,7 @@ case class AllForOneStrategy(maxNrOfRetries: Int = -1, withinTimeRange: Duration SupervisorStrategy.maxNrOfRetriesOption(maxNrOfRetries), SupervisorStrategy.withinTimeRangeOption(withinTimeRange).map(_.toMillis.toInt)) - def handleChildTerminated(context: ActorContext, child: ActorRef, children: Iterable[ActorRef]): Unit = { - children foreach (context.stop(_)) - //TODO optimization to drop all children here already? - } + def handleChildTerminated(context: ActorContext, child: ActorRef, children: Iterable[ActorRef]): Unit = {} def processFailure(context: ActorContext, restart: Boolean, child: ActorRef, cause: Throwable, stats: ChildRestartStats, children: Iterable[ChildRestartStats]): Unit = { if (children.nonEmpty) { From 72ab6429c21e4db949d8623251b412aed5e487c7 Mon Sep 17 00:00:00 2001 From: Roland Date: Tue, 21 Feb 2012 08:51:51 +0100 Subject: [PATCH 2/2] document AllForOneStrategy better, see #1851 --- akka-docs/general/supervision.rst | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/akka-docs/general/supervision.rst b/akka-docs/general/supervision.rst index 2aa9ceba0a..99efb0378d 100644 --- a/akka-docs/general/supervision.rst +++ b/akka-docs/general/supervision.rst @@ -7,6 +7,8 @@ This chapter outlines the concept behind supervision, the primitives offered and their semantics. For details on how that translates into real code, please refer to the corresponding chapters for Scala and Java APIs. +.. _supervision-directives: + What Supervision Means ---------------------- @@ -110,3 +112,39 @@ external resource, which may also be one of its own children. If a third party terminates a child by way of the ``system.stop(child)`` method or sending a :class:`PoisonPill`, the supervisor might well be affected. +One-For-One Strategy vs. All-For-One Strategy +--------------------------------------------- + +There are two classes of supervision strategies which come with Akka: +:class:`OneForOneStrategy` and :class:`AllForOneStrategy`. Both are configured +with a mapping from exception type to supervision directive (see +:ref:`above `) and limits on how often a child is allowed to fail +before terminating it. The difference between them is that the former applies +the obtained directive only to the failed child, whereas the latter applies it +to all siblings as well. Normally, you should use the +:class:`OneForOneStrategy`, which also is the default if none is specified +explicitly. + +The :class:`AllForOneStrategy` is applicable in cases where the ensemble of +children has so tight dependencies among them, that a failure of one child +affects the function of the others, i.e. they are intricably linked. Since a +restart does not clear out the mailbox, it often is best to stop the children +upon failure and re-create them explicitly from the supervisor (by watching the +children’s lifecycle); otherwise you have to make sure that it is no problem +for any of the actors to receive a message which was queued before the restart +but processed afterwards. + +Normally stopping a child (i.e. not in response to a failure) will not +automatically terminate the other children in an all-for-one strategy, that can +easily be done by watching their lifecycle: if the :class:`Terminated` message +is not handled by the supervisor, it will throw a :class:`DeathPathException` +which (depending on its supervisor) will restart it, and the default +:meth:`preRestart` action will terminate all children. Of course this can be +handled explicitly as well. + +Please note that creating one-off actors from an all-for-one supervisor entails +that failures escalated by the temporary actor will affect all the permanent +ones. If this is not desired, install an intermediate supervisor; this can very +easily be done by declaring a router of size 1 for the worker, see +:ref:`routing-scala` or :ref:`routing-java`. +