From 6bbbceaf6c21976907315f0322c79027722a5a72 Mon Sep 17 00:00:00 2001 From: Patrik Nordwall Date: Wed, 14 Dec 2011 19:25:32 +0100 Subject: [PATCH] DOC: Updated preRestart --- .../akka/docs/actor/UntypedActorTestBase.java | 5 +- akka-docs/java/untyped-actors.rst | 72 +++++++++---------- akka-docs/scala/actors.rst | 9 ++- 3 files changed, 45 insertions(+), 41 deletions(-) diff --git a/akka-docs/java/code/akka/docs/actor/UntypedActorTestBase.java b/akka-docs/java/code/akka/docs/actor/UntypedActorTestBase.java index 6039286598..3cc234176b 100644 --- a/akka-docs/java/code/akka/docs/actor/UntypedActorTestBase.java +++ b/akka-docs/java/code/akka/docs/actor/UntypedActorTestBase.java @@ -78,8 +78,7 @@ public class UntypedActorTestBase { ActorSystem system = ActorSystem.create("MySystem"); //#creating-props MessageDispatcher dispatcher = system.dispatcherFactory().lookup("my-dispatcher"); - ActorRef myActor = system.actorOf( - new Props().withCreator(MyUntypedActor.class).withDispatcher(dispatcher), + ActorRef myActor = system.actorOf(new Props().withCreator(MyUntypedActor.class).withDispatcher(dispatcher), "myactor"); //#creating-props myActor.tell("test"); @@ -166,6 +165,8 @@ public class UntypedActorTestBase { } public void preRestart(Throwable reason, Option message) { + for (ActorRef each : getContext().getChildren()) + getContext().stop(each); postStop(); } diff --git a/akka-docs/java/untyped-actors.rst b/akka-docs/java/untyped-actors.rst index 4324aadf19..c680865b6b 100644 --- a/akka-docs/java/untyped-actors.rst +++ b/akka-docs/java/untyped-actors.rst @@ -62,7 +62,7 @@ a top level actor, that is supervised by the system (internal guardian actor). .. includecode:: code/akka/docs/actor/FirstUntypedActor.java#context-actorOf Actors are automatically started asynchronously when created. -When you create the ``UntypedActor`` then it will automatically call the ``preStart`` +When you create the ``UntypedActor`` then it will automatically call the ``preStart`` callback method on the ``UntypedActor`` class. This is an excellent place to add initialization code for the actor. @@ -76,11 +76,11 @@ add initialization code for the actor. Creating Actors with non-default constructor -------------------------------------------- -If your UntypedActor has a constructor that takes parameters then you can't create it using 'actorOf(clazz)'. -Instead you can use a variant of ``actorOf`` that takes an instance of an 'UntypedActorFactory' -in which you can create the Actor in any way you like. If you use this method then you to make sure that -no one can get a reference to the actor instance. If they can get a reference it then they can -touch state directly in bypass the whole actor dispatching mechanism and create race conditions +If your UntypedActor has a constructor that takes parameters then you can't create it using 'actorOf(clazz)'. +Instead you can use a variant of ``actorOf`` that takes an instance of an 'UntypedActorFactory' +in which you can create the Actor in any way you like. If you use this method then you to make sure that +no one can get a reference to the actor instance. If they can get a reference it then they can +touch state directly in bypass the whole actor dispatching mechanism and create race conditions which can lead to corrupt data. Here is an example: @@ -92,7 +92,7 @@ This way of creating the Actor is also great for integrating with Dependency Inj Creating Actors with Props -------------------------- -``Props`` is a configuration object to specify additional things for the actor to +``Props`` is a configuration object to specify additional things for the actor to be created, such as the ``MessageDispatcher``. .. includecode:: code/akka/docs/actor/UntypedActorTestBase.java#creating-props @@ -152,7 +152,7 @@ processing a message. This restart involves the hooks mentioned above: message, e.g. when a supervisor does not trap the exception and is restarted in turn by its supervisor. This method is the best place for cleaning up, preparing hand-over to the fresh actor instance, etc. - By default it calls :meth:`postStop`. + By default it stops all children and calls :meth:`postStop`. 2. The initial factory from the ``actorOf`` call is used to produce the fresh instance. 3. The new actor’s :meth:`postRestart` method is invoked with the exception @@ -162,7 +162,7 @@ processing a message. This restart involves the hooks mentioned above: An actor restart replaces only the actual actor object; the contents of the mailbox and the hotswap stack are unaffected by the restart, so processing of -messages will resume after the :meth:`postRestart` hook returns. The message +messages will resume after the :meth:`postRestart` hook returns. The message that triggered the exception will not be received again. Any message sent to an actor while it is being restarted will be queued to its mailbox as usual. @@ -172,9 +172,9 @@ Stop Hook After stopping an actor, its :meth:`postStop` hook is called, which may be used e.g. for deregistering this actor from other services. This hook is guaranteed -to run after message queuing has been disabled for this actor, i.e. messages -sent to a stopped actor will be redirected to the :obj:`deadLetters` of the -:obj:`ActorSystem`. +to run after message queuing has been disabled for this actor, i.e. messages +sent to a stopped actor will be redirected to the :obj:`deadLetters` of the +:obj:`ActorSystem`. Identifying Actors @@ -188,7 +188,7 @@ Messages and immutability **IMPORTANT**: Messages can be any kind of object but have to be immutable. Akka can’t enforce immutability (yet) so this has to be by -convention. +convention. Here is an example of an immutable message: @@ -207,8 +207,8 @@ Messages are sent to an Actor through one of the following methods. Message ordering is guaranteed on a per-sender basis. -In all these methods you have the option of passing along your own ``ActorRef``. -Make it a practice of doing so because it will allow the receiver actors to be able to respond +In all these methods you have the option of passing along your own ``ActorRef``. +Make it a practice of doing so because it will allow the receiver actors to be able to respond to your message, since the sender reference is sent along with the message. Tell: Fire-forget @@ -229,7 +229,7 @@ to reply to the original sender, by using ``getSender().tell(replyMsg)``. actor.tell("Hello", getSelf()); -If invoked without the sender parameter the sender will be +If invoked without the sender parameter the sender will be :obj:`deadLetters` actor reference in the target actor. Ask: Send-And-Receive-Future @@ -244,11 +244,11 @@ will immediately return a :class:`Future`: Future future = actorRef.ask("Hello", timeoutMillis); The receiving actor should reply to this message, which will complete the -future with the reply message as value; ``getSender.tell(result)``. +future with the reply message as value; ``getSender.tell(result)``. -To complete the future with an exception you need send a Failure message to the sender. -This is not done automatically when an actor throws an exception while processing a -message. +To complete the future with an exception you need send a Failure message to the sender. +This is not done automatically when an actor throws an exception while processing a +message. .. includecode:: code/akka/docs/actor/UntypedActorTestBase.java#reply-exception @@ -258,16 +258,16 @@ specified as parameter to the ``ask`` method. See :ref:`futures-java` for more information on how to await or query a future. -The ``onComplete``, ``onResult``, or ``onTimeout`` methods of the ``Future`` can be -used to register a callback to get a notification when the Future completes. +The ``onComplete``, ``onResult``, or ``onTimeout`` methods of the ``Future`` can be +used to register a callback to get a notification when the Future completes. Gives you a way to avoid blocking. .. warning:: When using future callbacks, inside actors you need to carefully avoid closing over - the containing actor’s reference, i.e. do not call methods or access mutable state - on the enclosing actor from within the callback. This would break the actor - encapsulation and may introduce synchronization bugs and race conditions because + the containing actor’s reference, i.e. do not call methods or access mutable state + on the enclosing actor from within the callback. This would break the actor + encapsulation and may introduce synchronization bugs and race conditions because the callback will be scheduled concurrently to the enclosing actor. Unfortunately there is not yet a way to detect these illegal accesses at compile time. See also: :ref:`jmm-shared-state` @@ -297,7 +297,7 @@ You need to pass along your context variable as well. Receive messages ================ -When an actor receives a message it is passed into the ``onReceive`` method, this is +When an actor receives a message it is passed into the ``onReceive`` method, this is an abstract method on the ``UntypedActor`` base class that needs to be defined. Here is an example: @@ -340,17 +340,17 @@ message. Stopping actors =============== -Actors are stopped by invoking the ``stop`` method of the ``ActorRef``. +Actors are stopped by invoking the ``stop`` method of the ``ActorRef``. The actual termination of the actor is performed asynchronously, i.e. -``stop`` may return before the actor is stopped. +``stop`` may return before the actor is stopped. .. code-block:: java actor.stop(); -Processing of the current message, if any, will continue before the actor is stopped, +Processing of the current message, if any, will continue before the actor is stopped, but additional messages in the mailbox will not be processed. By default these -messages are sent to the :obj:`deadLetters` of the :obj:`ActorSystem`, but that +messages are sent to the :obj:`deadLetters` of the :obj:`ActorSystem`, but that depends on the mailbox implementation. When stop is called then a call to the ``def postStop`` callback method will @@ -365,7 +365,7 @@ take place. The ``Actor`` can use this callback to implement shutdown behavior. All Actors are stopped when the ``ActorSystem`` is stopped. Supervised actors are stopped when the supervisor is stopped, i.e. children are stopped -when parent is stopped. +when parent is stopped. PoisonPill @@ -405,7 +405,7 @@ To hotswap the Actor using ``getContext().become``: .. includecode:: code/akka/docs/actor/UntypedActorTestBase.java :include: import-procedure,hot-swap-actor -The ``become`` method is useful for many different things, such as to implement +The ``become`` method is useful for many different things, such as to implement a Finite State Machine (FSM). Here is another little cute example of ``become`` and ``unbecome`` in action: @@ -462,9 +462,9 @@ messages on that mailbox, will be there as well. What happens to the actor ------------------------- -If an exception is thrown, the actor instance is discarded and a new instance is +If an exception is thrown, the actor instance is discarded and a new instance is created. This new instance will now be used in the actor references to this actor -(so this is done invisible to the developer). Note that this means that current -state of the failing actor instance is lost if you don't store and restore it in -``preRestart`` and ``postRestart`` callbacks. +(so this is done invisible to the developer). Note that this means that current +state of the failing actor instance is lost if you don't store and restore it in +``preRestart`` and ``postRestart`` callbacks. diff --git a/akka-docs/scala/actors.rst b/akka-docs/scala/actors.rst index 2d11ea4894..39f4647b90 100644 --- a/akka-docs/scala/actors.rst +++ b/akka-docs/scala/actors.rst @@ -54,7 +54,7 @@ Creating Actors with default constructor ---------------------------------------- .. includecode:: code/ActorDocSpec.scala -:include: imports2,system-actorOf + :include: imports2,system-actorOf The call to :meth:`actorOf` returns an instance of ``ActorRef``. This is a handle to the ``Actor`` instance which you can use to interact with the ``Actor``. The @@ -151,7 +151,10 @@ The remaining visible methods are user-overridable life-cycle hooks which are described in the following:: def preStart() {} - def preRestart(reason: Throwable, message: Option[Any]) { postStop() } + def preRestart(reason: Throwable, message: Option[Any]) { + context.children foreach (context.stop(_)) + postStop() + } def postRestart(reason: Throwable) { preStart() } def postStop() {} @@ -185,7 +188,7 @@ processing a message. This restart involves the hooks mentioned above: message, e.g. when a supervisor does not trap the exception and is restarted in turn by its supervisor. This method is the best place for cleaning up, preparing hand-over to the fresh actor instance, etc. - By default it calls :meth:`postStop`. + By default it stops all children and calls :meth:`postStop`. 2. The initial factory from the ``actorOf`` call is used to produce the fresh instance. 3. The new actor’s :meth:`postRestart` method is invoked with the exception