Merge with master

This commit is contained in:
Viktor Klang 2011-12-15 14:10:08 +01:00
commit 009853f2f6
168 changed files with 2942 additions and 6005 deletions

View file

@ -2,4 +2,4 @@ package akka.docs.actor
import org.scalatest.junit.JUnitSuite
class UntypedActorTest extends UntypedActorTestBase with JUnitSuite
class SchedulerDocTest extends SchedulerDocTestBase with JUnitSuite

View file

@ -0,0 +1,85 @@
package akka.docs.actor;
//#imports1
import akka.actor.Props;
import akka.util.Duration;
import java.util.concurrent.TimeUnit;
//#imports1
//#imports2
import akka.actor.UntypedActor;
import akka.actor.UntypedActorFactory;
import akka.actor.Cancellable;
//#imports2
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.testkit.AkkaSpec;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class SchedulerDocTestBase {
ActorSystem system;
ActorRef testActor;
@Before
public void setUp() {
system = ActorSystem.create("MySystem", AkkaSpec.testConf());
testActor = system.actorOf(new Props().withCreator(MyUntypedActor.class));
}
@After
public void tearDown() {
system.shutdown();
}
@Test
public void scheduleOneOffTask() {
//#schedule-one-off-message
//Schedules to send the "foo"-message to the testActor after 50ms
system.scheduler().scheduleOnce(Duration.create(50, TimeUnit.MILLISECONDS), testActor, "foo");
//#schedule-one-off-message
//#schedule-one-off-thunk
//Schedules a Runnable to be executed (send the current time) to the testActor after 50ms
system.scheduler().scheduleOnce(Duration.create(50, TimeUnit.MILLISECONDS), new Runnable() {
@Override
public void run() {
testActor.tell(System.currentTimeMillis());
}
});
//#schedule-one-off-thunk
}
@Test
public void scheduleRecurringTask() {
//#schedule-recurring
ActorRef tickActor = system.actorOf(new Props().withCreator(new UntypedActorFactory() {
public UntypedActor create() {
return new UntypedActor() {
public void onReceive(Object message) {
if (message.equals("Tick")) {
// Do someting
}
}
};
}
}));
//This will schedule to send the Tick-message
//to the tickActor after 0ms repeating every 50ms
Cancellable cancellable = system.scheduler().schedule(Duration.Zero(), Duration.create(50, TimeUnit.MILLISECONDS),
tickActor, "Tick");
//This cancels further Ticks to be sent
cancellable.cancel();
//#schedule-recurring
system.stop(tickActor);
}
}

View file

@ -0,0 +1,5 @@
package akka.docs.actor
import org.scalatest.junit.JUnitSuite
class UntypedActorDocTest extends UntypedActorDocTestBase with JUnitSuite

View file

@ -4,24 +4,21 @@ package akka.docs.actor;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
//#imports
//#import-future
import akka.dispatch.Future;
import akka.dispatch.Await;
import akka.util.Duration;
import akka.util.Timeout;
//#import-future
//#import-actors
import static akka.actor.Actors.*;
//#import-actors
//#import-procedure
import akka.japi.Procedure;
//#import-procedure
import akka.actor.Props;
@ -36,7 +33,26 @@ import java.util.concurrent.TimeUnit;
import static org.junit.Assert.*;
public class UntypedActorTestBase {
public class UntypedActorDocTestBase {
@Test
public void createProps() {
//#creating-props-config
Props props1 = new Props();
Props props2 = new Props(MyUntypedActor.class);
Props props3 = new Props(new UntypedActorFactory() {
public UntypedActor create() {
return new MyUntypedActor();
}
});
Props props4 = props1.withCreator(new UntypedActorFactory() {
public UntypedActor create() {
return new MyUntypedActor();
}
});
Props props5 = props4.withTimeout(new Timeout(1000));
//#creating-props-config
}
@Test
public void systemActorOf() {
@ -79,8 +95,8 @@ public class UntypedActorTestBase {
//#creating-props
MessageDispatcher dispatcher = system.dispatcherFactory().lookup("my-dispatcher");
ActorRef myActor = system.actorOf(
new Props().withCreator(MyUntypedActor.class).withDispatcher(dispatcher),
"myactor");
new Props().withCreator(MyUntypedActor.class).withDispatcher(dispatcher),
"myactor");
//#creating-props
myActor.tell("test");
system.shutdown();
@ -166,6 +182,8 @@ public class UntypedActorTestBase {
}
public void preRestart(Throwable reason, Option<Object> message) {
for (ActorRef each : getContext().getChildren())
getContext().stop(each);
postStop();
}

View file

@ -28,7 +28,7 @@ import com.typesafe.config.ConfigFactory;
import akka.actor.ActorSystem;
import akka.docs.actor.MyUntypedActor;
import akka.docs.actor.UntypedActorTestBase.MyActor;
import akka.docs.actor.UntypedActorDocTestBase.MyActor;
import akka.testkit.AkkaSpec;
public class DispatcherDocTestBase {

View file

@ -0,0 +1,5 @@
package akka.docs.extension
import org.scalatest.junit.JUnitSuite
class ExtensionDocTest extends ExtensionDocTestBase with JUnitSuite

View file

@ -0,0 +1,70 @@
package akka.docs.extension;
//#imports
import akka.actor.*;
import java.util.concurrent.atomic.AtomicLong;
//#imports
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class ExtensionDocTestBase {
//#extension
public static class CountExtensionImpl implements Extension {
//Since this Extension is a shared instance
// per ActorSystem we need to be threadsafe
private final AtomicLong counter = new AtomicLong(0);
//This is the operation this Extension provides
public long increment() {
return counter.incrementAndGet();
}
}
//#extension
//#extensionid
static class CountExtensionId extends AbstractExtensionId<CountExtensionImpl> {
//This method will be called by Akka
// to instantiate our Extension
public CountExtensionImpl createExtension(ActorSystemImpl i) {
return new CountExtensionImpl();
}
}
//This will be the identifier of our CountExtension
public final static CountExtensionId CountExtension = new CountExtensionId();
//#extensionid
//#extensionid-provider
static class CountExtensionIdProvider implements ExtensionIdProvider {
public CountExtensionId lookup() {
return CountExtension; //The public static final
}
}
//#extensionid-provider
//#extension-usage-actor
static class MyActor extends UntypedActor {
public void onReceive(Object msg) {
CountExtension.get(getContext().system()).increment();
}
}
//#extension-usage-actor
@Test public void demonstrateHowToCreateAndUseAnAkkaExtensionInJava() {
final ActorSystem system = null;
try {
//#extension-usage
CountExtension.get(system).increment();
//#extension-usage
} catch(Exception e) {
//do nothing
}
}
}

View file

@ -6,7 +6,7 @@ Dispatchers (Java)
.. sidebar:: Contents
.. contents:: :local:
The Dispatcher is an important piece that allows you to configure the right semantics and parameters for optimal performance, throughput and scalability. Different Actors have different needs.
Akka supports dispatchers for both event-driven lightweight threads, allowing creation of millions of threads on a single workstation, and thread-based Actors, where each dispatcher is bound to a dedicated OS thread.
@ -44,7 +44,7 @@ There are 4 different types of message dispatchers:
It is recommended to define the dispatcher in :ref:`configuration` to allow for tuning for different environments.
Example of a custom event-based dispatcher, which can be fetched with ``system.dispatcherFactory().lookup("my-dispatcher")``
Example of a custom event-based dispatcher, which can be fetched with ``system.dispatcherFactory().lookup("my-dispatcher")``
as in the example above:
.. includecode:: ../scala/code/akka/docs/dispatcher/DispatcherDocSpec.scala#my-dispatcher-config
@ -115,7 +115,7 @@ Priority event-based
^^^^^^^^^^^^^^^^^^^^
Sometimes it's useful to be able to specify priority order of messages, that is done by using Dispatcher and supply
an UnboundedPriorityMailbox or BoundedPriorityMailbox with a ``java.util.Comparator[Envelope]`` or use a
an UnboundedPriorityMailbox or BoundedPriorityMailbox with a ``java.util.Comparator[Envelope]`` or use a
``akka.dispatch.PriorityGenerator`` (recommended).
Creating a Dispatcher using PriorityGenerator:
@ -129,9 +129,9 @@ Work-sharing event-based
The ``BalancingDispatcher`` is a variation of the ``Dispatcher`` in which Actors of the same type can be set up to
share this dispatcher and during execution time the different actors will steal messages from other actors if they
have less messages to process.
have less messages to process.
Although the technique used in this implementation is commonly known as "work stealing", the actual implementation is probably
best described as "work donating" because the actor of which work is being stolen takes the initiative.
best described as "work donating" because the actor of which work is being stolen takes the initiative.
This can be a great way to improve throughput at the cost of a little higher latency.
.. includecode:: ../scala/code/akka/docs/dispatcher/DispatcherDocSpec.scala#my-balancing-config
@ -154,8 +154,9 @@ if not specified otherwise.
akka {
actor {
default-dispatcher {
task-queue-size = 1000 # If negative (or zero) then an unbounded mailbox is used (default)
# If positive then a bounded mailbox is used and the capacity is set to the number specified
# If negative (or zero) then an unbounded mailbox is used (default)
# If positive then a bounded mailbox is used and the capacity is set to the number specified
task-queue-size = 1000
}
}
}

View file

@ -0,0 +1,63 @@
.. _extending-akka:
Akka Extensions
===============
.. sidebar:: Contents
.. contents:: :local:
If you want to add features to Akka, there is a very elegant, but powerful mechanism for doing so.
It's called Akka Extensions and is comprised of 2 basic components: an ``Extension`` and an ``ExtensionId``.
Extensions will only be loaded once per ``ActorSystem``, which will be managed by Akka.
You can choose to have your Extension loaded on-demand or at ``ActorSystem`` creation time through the Akka configuration.
Details on how to make that happens are below, in the "Loading from Configuration" section.
.. warning::
Since an extension is a way to hook into Akka itself, the implementor of the extension needs to
ensure the thread safety of his/her extension.
Building an Extension
---------------------
So let's create a sample extension that just lets us count the number of times something has happened.
First, we define what our ``Extension`` should do:
.. includecode:: code/akka/docs/extension/ExtensionDocTestBase.java
:include: imports,extension
Then we need to create an ``ExtensionId`` for our extension so we can grab ahold of it.
.. includecode:: code/akka/docs/extension/ExtensionDocTestBase.java
:include: imports,extensionid
Wicked! Now all we need to do is to actually use it:
.. includecode:: code/akka/docs/extension/ExtensionDocTestBase.java
:include: extension-usage
Or from inside of an Akka Actor:
.. includecode:: code/akka/docs/extension/ExtensionDocTestBase.java
:include: extension-usage-actor
That's all there is to it!
Loading from Configuration
--------------------------
To be able to load extensions from your Akka configuration you must add FQCNs of implementations of either ``ExtensionId`` or ``ExtensionIdProvider``
in the "akka.extensions" section of the config you provide to your ``ActorSystem``.
.. includecode:: code/akka/docs/extension/ExtensionDocTestBase.java
:include: extensionid-provider
Applicability
-------------
The sky is the limit!
By the way, did you know that Akka's ``Typed Actors``, ``Serialization`` and other features are implemented as Akka Extensions?

View file

@ -9,11 +9,12 @@ Java API
untyped-actors
typed-actors
logging
scheduler
futures
dataflow
stm
transactors
fault-tolerance
dispatchers
routing
guice-integration
extending-akka

View file

@ -25,14 +25,14 @@ The source object is translated to a String according to the following rules:
* in case of a class an approximation of its simpleName
* and in all other cases the simpleName of its class
The log message may contain argument placeholders ``{}``, which will be substituted if the log level
The log message may contain argument placeholders ``{}``, which will be substituted if the log level
is enabled.
Event Handler
=============
Logging is performed asynchronously through an event bus. You can configure which event handlers that should
subscribe to the logging events. That is done using the 'event-handlers' element in the :ref:`configuration`.
Logging is performed asynchronously through an event bus. You can configure which event handlers that should
subscribe to the logging events. That is done using the 'event-handlers' element in the :ref:`configuration`.
Here you can also define the log level.
.. code-block:: ruby
@ -40,16 +40,17 @@ Here you can also define the log level.
akka {
# Event handlers to register at boot time (Logging$DefaultLogger logs to STDOUT)
event-handlers = ["akka.event.Logging$DefaultLogger"]
loglevel = "DEBUG" # Options: ERROR, WARNING, INFO, DEBUG
# Options: ERROR, WARNING, INFO, DEBUG
loglevel = "DEBUG"
}
The default one logs to STDOUT and is registered by default. It is not intended to be used for production. There is also an :ref:`slf4j-java`
The default one logs to STDOUT and is registered by default. It is not intended to be used for production. There is also an :ref:`slf4j-java`
event handler available in the 'akka-slf4j' module.
Example of creating a listener:
.. includecode:: code/akka/docs/event/LoggingDocTestBase.java
:include: imports,imports-listener,my-event-listener
:include: imports,imports-listener,my-event-listener
.. _slf4j-java:
@ -57,7 +58,7 @@ Example of creating a listener:
SLF4J
=====
Akka provides an event handler for `SL4FJ <http://www.slf4j.org/>`_. This module is available in the 'akka-slf4j.jar'.
Akka provides an event handler for `SL4FJ <http://www.slf4j.org/>`_. This module is available in the 'akka-slf4j.jar'.
It has one single dependency; the slf4j-api jar. In runtime you also need a SLF4J backend, we recommend `Logback <http://logback.qos.ch/>`_:
.. code-block:: xml
@ -69,10 +70,10 @@ It has one single dependency; the slf4j-api jar. In runtime you also need a SLF4
<scope>runtime</scope>
</dependency>
You need to enable the Slf4jEventHandler in the 'event-handlers' element in
the :ref:`configuration`. Here you can also define the log level of the event bus.
You need to enable the Slf4jEventHandler in the 'event-handlers' element in
the :ref:`configuration`. Here you can also define the log level of the event bus.
More fine grained log levels can be defined in the configuration of the SLF4J backend
(e.g. logback.xml). The String representation of the source object that is used when
(e.g. logback.xml). The String representation of the source object that is used when
creating the ``LoggingAdapter`` correspond to the name of the SL4FJ logger.
.. code-block:: ruby
@ -89,9 +90,9 @@ Since the logging is done asynchronously the thread in which the logging was per
Mapped Diagnostic Context (MDC) with attribute name ``sourceThread``.
With Logback the thread name is available with ``%X{sourceThread}`` specifier within the pattern layout configuration::
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout>
<pattern>%date{ISO8601} %-5level %logger{36} %X{sourceThread} - %msg%n</pattern>
</layout>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout>
<pattern>%date{ISO8601} %-5level %logger{36} %X{sourceThread} - %msg%n</pattern>
</layout>
</appender>

View file

@ -0,0 +1,53 @@
.. _scheduler-java:
##################
Scheduler (Java)
##################
Sometimes the need for making things happen in the future arises, and where do you go look then?
Look no further than ``ActorSystem``! There you find the :meth:`scheduler` method that returns an instance
of akka.actor.Scheduler, this instance is unique per ActorSystem and is used internally for scheduling things
to happen at specific points in time. Please note that the scheduled tasks are executed by the default
``MessageDispatcher`` of the ``ActorSystem``.
You can schedule sending of messages to actors and execution of tasks (functions or Runnable).
You will get a ``Cancellable`` back that you can call :meth:`cancel` on to cancel the execution of the
scheduled operation.
Some examples
-------------
.. includecode:: code/akka/docs/actor/SchedulerDocTestBase.java
:include: imports1,schedule-one-off-message
.. includecode:: code/akka/docs/actor/SchedulerDocTestBase.java
:include: schedule-one-off-thunk
.. includecode:: code/akka/docs/actor/SchedulerDocTestBase.java
:include: imports1,imports2,schedule-recurring
From ``akka.actor.ActorSystem``
-------------------------------
.. includecode:: ../../akka-actor/src/main/scala/akka/actor/ActorSystem.scala
:include: scheduler
The Scheduler interface
-----------------------
.. includecode:: ../../akka-actor/src/main/scala/akka/actor/Scheduler.scala
:include: scheduler
The Cancellable interface
-------------------------
This allows you to ``cancel`` something that has been scheduled for execution.
.. warning::
This does not abort the execution of the task, if it had already been started.
.. includecode:: ../../akka-actor/src/main/scala/akka/actor/Scheduler.scala
:include: cancellable

View file

@ -0,0 +1,6 @@
.. _transactors-java:
Transactors (Java)
==================
The Akka Transactors module has not been migrated to Akka 2.0-SNAPSHOT yet.

View file

@ -39,10 +39,27 @@ Here is an example:
.. includecode:: code/akka/docs/actor/MyUntypedActor.java#my-untyped-actor
Props
-----
``Props`` is a configuration class to specify options for the creation
of actors. Here are some examples on how to create a ``Props`` instance.
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#creating-props-config
Creating Actors with Props
--------------------------
Actors are created by passing in a ``Props`` instance into the ``actorOf`` factory method.
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#creating-props
Creating Actors with default constructor
----------------------------------------
.. includecode:: code/akka/docs/actor/UntypedActorTestBase.java
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java
:include: imports,system-actorOf
The call to :meth:`actorOf` returns an instance of ``ActorRef``. This is a handle to
@ -62,7 +79,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,26 +93,16 @@ 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
which can lead to corrupt data.
If your UntypedActor has a constructor that takes parameters then you can't create it using
'actorOf(new Props(clazz))'. Then you can instead pass in 'new Props(new UntypedActorFactory() {..})'
in which you can create the Actor in any way you like.
Here is an example:
.. includecode:: code/akka/docs/actor/UntypedActorTestBase.java#creating-constructor
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#creating-constructor
This way of creating the Actor is also great for integrating with Dependency Injection (DI) frameworks like Guice or Spring.
Creating Actors with Props
--------------------------
``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
This way of creating the Actor is also great for integrating with Dependency Injection
(DI) frameworks like Guice or Spring.
UntypedActor API
@ -119,7 +126,7 @@ In addition, it offers:
The remaining visible methods are user-overridable life-cycle hooks which are
described in the following:
.. includecode:: code/akka/docs/actor/UntypedActorTestBase.java#lifecycle-callbacks
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#lifecycle-callbacks
The implementations shown above are the defaults provided by the :class:`UntypedActor`
class.
@ -152,7 +159,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 actors :meth:`postRestart` method is invoked with the exception
@ -162,7 +169,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 +179,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 +195,7 @@ Messages and immutability
**IMPORTANT**: Messages can be any kind of object but have to be
immutable. Akka cant enforce immutability (yet) so this has to be by
convention.
convention.
Here is an example of an immutable message:
@ -207,8 +214,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 +236,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,13 +251,13 @@ 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
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#reply-exception
If the actor does not complete the future, it will expire after the timeout period,
specified as parameter to the ``ask`` method.
@ -258,16 +265,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 actors 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 actors 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`
@ -278,7 +285,7 @@ even if that entails waiting for it (but keep in mind that waiting inside an
actor is prone to dead-locks, e.g. if obtaining the result depends on
processing another message on this actor).
.. includecode:: code/akka/docs/actor/UntypedActorTestBase.java
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java
:include: import-future,using-ask
Forward message
@ -297,7 +304,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 +347,15 @@ message.
Stopping actors
===============
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.
Actors are stopped by invoking the :meth:`stop` method of a ``ActorRefFactory``,
i.e. ``ActorContext`` or ``ActorSystem``. Typically the context is used for stopping
child actors and the system for stopping top level actors. The actual termination of
the actor is performed asynchronously, i.e. :meth:`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 +370,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
@ -381,7 +386,7 @@ If the ``PoisonPill`` was sent with ``ask``, the ``Future`` will be completed wi
Use it like this:
.. includecode:: code/akka/docs/actor/UntypedActorTestBase.java
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java
:include: import-actors,poison-pill
.. _UntypedActor.HotSwap:
@ -402,10 +407,10 @@ The hotswapped code is kept in a Stack which can be pushed and popped.
To hotswap the Actor using ``getContext().become``:
.. includecode:: code/akka/docs/actor/UntypedActorTestBase.java
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.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:
@ -432,7 +437,7 @@ through regular supervisor semantics.
Use it like this:
.. includecode:: code/akka/docs/actor/UntypedActorTestBase.java
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java
:include: import-actors,kill
Actors and exceptions
@ -462,9 +467,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.