document Specs2 + TestKit, see #2068, plus fix up broken includes
- include move of doc samples out of akka package also in the includecode directives - fix broken serialization docs, which require one thing in the akka package
This commit is contained in:
parent
7d342e5c96
commit
dd30e81a1a
44 changed files with 681 additions and 555 deletions
|
|
@ -256,7 +256,7 @@ result::
|
|||
You may also specify and parse the configuration programmatically in other ways when instantiating
|
||||
the ``ActorSystem``.
|
||||
|
||||
.. includecode:: code/akka/docs/config/ConfigDocSpec.scala
|
||||
.. includecode:: code/docs/config/ConfigDocSpec.scala
|
||||
:include: imports,custom-config
|
||||
|
||||
Reading configuration from a custom location
|
||||
|
|
@ -301,7 +301,7 @@ you could put a config string in code using
|
|||
You can also combine your custom config with the usual config,
|
||||
that might look like:
|
||||
|
||||
.. includecode:: code/akka/docs/config/ConfigDoc.java
|
||||
.. includecode:: code/docs/config/ConfigDoc.java
|
||||
:include: java-custom-config
|
||||
|
||||
When working with ``Config`` objects, keep in mind that there are
|
||||
|
|
|
|||
|
|
@ -40,17 +40,17 @@ application. An ``ActorSystem`` is required to create the underlying Actors. See
|
|||
|
||||
Here is an example of creating an Agent:
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocTest.java
|
||||
.. includecode:: code/docs/agent/AgentDocTest.java
|
||||
:include: import-system,import-agent
|
||||
:language: java
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocTest.java#create
|
||||
.. includecode:: code/docs/agent/AgentDocTest.java#create
|
||||
:language: java
|
||||
|
||||
An Agent will be running until you invoke ``close`` on it. Then it will be
|
||||
eligible for garbage collection (unless you hold on to it in some way).
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocTest.java#close
|
||||
.. includecode:: code/docs/agent/AgentDocTest.java#close
|
||||
:language: java
|
||||
|
||||
|
||||
|
|
@ -65,10 +65,10 @@ the update will be applied but dispatches to an Agent from a single thread will
|
|||
occur in order. You apply a value or a function by invoking the ``send``
|
||||
function.
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocTest.java#import-function
|
||||
.. includecode:: code/docs/agent/AgentDocTest.java#import-function
|
||||
:language: java
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocTest.java#send
|
||||
.. includecode:: code/docs/agent/AgentDocTest.java#send
|
||||
:language: java
|
||||
|
||||
You can also dispatch a function to update the internal state but on its own
|
||||
|
|
@ -77,7 +77,7 @@ long-running or blocking operations. You do this with the ``sendOff``
|
|||
method. Dispatches using either ``sendOff`` or ``send`` will still be executed
|
||||
in order.
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocTest.java#send-off
|
||||
.. includecode:: code/docs/agent/AgentDocTest.java#send-off
|
||||
:language: java
|
||||
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ Reading an Agent's value
|
|||
Agents can be dereferenced (you can get an Agent's value) by calling the get
|
||||
method:
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocTest.java#read-get
|
||||
.. includecode:: code/docs/agent/AgentDocTest.java#read-get
|
||||
:language: java
|
||||
|
||||
Reading an Agent's current value does not involve any message passing and
|
||||
|
|
@ -101,8 +101,8 @@ Awaiting an Agent's value
|
|||
It is also possible to read the value after all currently queued sends have
|
||||
completed. You can do this with ``await``:
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocTest.java#import-timeout
|
||||
.. includecode:: code/docs/agent/AgentDocTest.java#import-timeout
|
||||
:language: java
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocTest.java#read-await
|
||||
.. includecode:: code/docs/agent/AgentDocTest.java#read-await
|
||||
:language: java
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ Setting the dispatcher for an Actor
|
|||
|
||||
So in case you want to give your ``Actor`` a different dispatcher than the default, you need to do two things, of which the first is:
|
||||
|
||||
.. includecode:: ../java/code/akka/docs/dispatcher/DispatcherDocTestBase.java#defining-dispatcher
|
||||
.. includecode:: ../java/code/docs/dispatcher/DispatcherDocTestBase.java#defining-dispatcher
|
||||
|
||||
.. note::
|
||||
The "dispatcherId" you specify in withDispatcher is in fact a path into your configuration.
|
||||
|
|
@ -27,11 +27,11 @@ So in case you want to give your ``Actor`` a different dispatcher than the defau
|
|||
|
||||
And then you just need to configure that dispatcher in your configuration:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/dispatcher/DispatcherDocSpec.scala#my-dispatcher-config
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#my-dispatcher-config
|
||||
|
||||
And here's another example that uses the "thread-pool-executor":
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/dispatcher/DispatcherDocSpec.scala#my-thread-pool-dispatcher-config
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#my-thread-pool-dispatcher-config
|
||||
|
||||
For more options, see the default-dispatcher section of the :ref:`configuration`.
|
||||
|
||||
|
|
@ -106,11 +106,11 @@ More dispatcher configuration examples
|
|||
|
||||
Configuring a ``PinnedDispatcher``:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/dispatcher/DispatcherDocSpec.scala#my-pinned-dispatcher-config
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#my-pinned-dispatcher-config
|
||||
|
||||
And then using it:
|
||||
|
||||
.. includecode:: ../java/code/akka/docs/dispatcher/DispatcherDocTestBase.java#defining-pinned-dispatcher
|
||||
.. includecode:: ../java/code/docs/dispatcher/DispatcherDocTestBase.java#defining-pinned-dispatcher
|
||||
|
||||
Mailboxes
|
||||
---------
|
||||
|
|
@ -162,15 +162,15 @@ Mailbox configuration examples
|
|||
|
||||
How to create a PriorityMailbox:
|
||||
|
||||
.. includecode:: ../java/code/akka/docs/dispatcher/DispatcherDocTestBase.java#prio-mailbox
|
||||
.. includecode:: ../java/code/docs/dispatcher/DispatcherDocTestBase.java#prio-mailbox
|
||||
|
||||
And then add it to the configuration:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/dispatcher/DispatcherDocSpec.scala#prio-dispatcher-config
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#prio-dispatcher-config
|
||||
|
||||
And then an example on how you would use it:
|
||||
|
||||
.. includecode:: ../java/code/akka/docs/dispatcher/DispatcherDocTestBase.java#prio-dispatcher
|
||||
.. includecode:: ../java/code/docs/dispatcher/DispatcherDocTestBase.java#prio-dispatcher
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
|
|||
|
|
@ -158,12 +158,12 @@ Classification`_ which enables registering to related sets of channels (as is
|
|||
used for :class:`RemoteLifeCycleMessage`). The following example demonstrates
|
||||
how a simple subscription works. Given a simple actor:
|
||||
|
||||
.. includecode:: code/akka/docs/event/LoggingDocTestBase.java#imports-deadletter
|
||||
.. includecode:: code/akka/docs/event/LoggingDocTestBase.java#deadletter-actor
|
||||
.. includecode:: code/docs/event/LoggingDocTestBase.java#imports-deadletter
|
||||
.. includecode:: code/docs/event/LoggingDocTestBase.java#deadletter-actor
|
||||
|
||||
it can be subscribed like this:
|
||||
|
||||
.. includecode:: code/akka/docs/event/LoggingDocTestBase.java#deadletters
|
||||
.. includecode:: code/docs/event/LoggingDocTestBase.java#deadletters
|
||||
|
||||
Default Handlers
|
||||
----------------
|
||||
|
|
|
|||
|
|
@ -25,22 +25,22 @@ So let's create a sample extension that just lets us count the number of times s
|
|||
|
||||
First, we define what our ``Extension`` should do:
|
||||
|
||||
.. includecode:: code/akka/docs/extension/ExtensionDocTestBase.java
|
||||
.. includecode:: code/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
|
||||
.. includecode:: code/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
|
||||
.. includecode:: code/docs/extension/ExtensionDocTestBase.java
|
||||
:include: extension-usage
|
||||
|
||||
Or from inside of an Akka Actor:
|
||||
|
||||
.. includecode:: code/akka/docs/extension/ExtensionDocTestBase.java
|
||||
.. includecode:: code/docs/extension/ExtensionDocTestBase.java
|
||||
:include: extension-usage-actor
|
||||
|
||||
That's all there is to it!
|
||||
|
|
@ -72,17 +72,17 @@ The :ref:`configuration` can be used for application specific settings. A good p
|
|||
|
||||
Sample configuration:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/extension/SettingsExtensionDocSpec.scala
|
||||
.. includecode:: ../scala/code/docs/extension/SettingsExtensionDocSpec.scala
|
||||
:include: config
|
||||
|
||||
The ``Extension``:
|
||||
|
||||
.. includecode:: code/akka/docs/extension/SettingsExtensionDocTestBase.java
|
||||
.. includecode:: code/docs/extension/SettingsExtensionDocTestBase.java
|
||||
:include: imports,extension,extensionid
|
||||
|
||||
|
||||
Use it:
|
||||
|
||||
.. includecode:: code/akka/docs/extension/SettingsExtensionDocTestBase.java
|
||||
.. includecode:: code/docs/extension/SettingsExtensionDocTestBase.java
|
||||
:include: extension-usage-actor
|
||||
|
||||
|
|
|
|||
|
|
@ -49,5 +49,5 @@ Step Description
|
|||
Full Source Code of the Fault Tolerance Sample (Java)
|
||||
------------------------------------------------------
|
||||
|
||||
.. includecode:: code/akka/docs/actor/japi/FaultHandlingDocSample.java#all
|
||||
.. includecode:: code/docs/actor/japi/FaultHandlingDocSample.java#all
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ sample as it is easy to follow the log output to understand what is happening in
|
|||
|
||||
fault-tolerance-sample
|
||||
|
||||
.. includecode:: code/akka/docs/actor/japi/FaultHandlingDocSample.java#all
|
||||
.. includecode:: code/docs/actor/japi/FaultHandlingDocSample.java#all
|
||||
:exclude: imports,messages,dummydb
|
||||
|
||||
Creating a Supervisor Strategy
|
||||
|
|
@ -35,7 +35,7 @@ in more depth.
|
|||
|
||||
For the sake of demonstration let us consider the following strategy:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingTestBase.java
|
||||
.. includecode:: code/docs/actor/FaultHandlingTestBase.java
|
||||
:include: strategy
|
||||
|
||||
I have chosen a few well-known exception types in order to demonstrate the
|
||||
|
|
@ -70,49 +70,49 @@ Test Application
|
|||
The following section shows the effects of the different directives in practice,
|
||||
wherefor a test setup is needed. First off, we need a suitable supervisor:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingTestBase.java
|
||||
.. includecode:: code/docs/actor/FaultHandlingTestBase.java
|
||||
:include: supervisor
|
||||
|
||||
This supervisor will be used to create a child, with which we can experiment:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingTestBase.java
|
||||
.. includecode:: code/docs/actor/FaultHandlingTestBase.java
|
||||
:include: child
|
||||
|
||||
The test is easier by using the utilities described in :ref:`akka-testkit`,
|
||||
where ``TestProbe`` provides an actor ref useful for receiving and inspecting replies.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingTestBase.java
|
||||
.. includecode:: code/docs/actor/FaultHandlingTestBase.java
|
||||
:include: testkit
|
||||
|
||||
Let us create actors:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingTestBase.java
|
||||
.. includecode:: code/docs/actor/FaultHandlingTestBase.java
|
||||
:include: create
|
||||
|
||||
The first test shall demonstrate the ``Resume`` directive, so we try it out by
|
||||
setting some non-initial state in the actor and have it fail:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingTestBase.java
|
||||
.. includecode:: code/docs/actor/FaultHandlingTestBase.java
|
||||
:include: resume
|
||||
|
||||
As you can see the value 42 survives the fault handling directive. Now, if we
|
||||
change the failure to a more serious ``NullPointerException``, that will no
|
||||
longer be the case:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingTestBase.java
|
||||
.. includecode:: code/docs/actor/FaultHandlingTestBase.java
|
||||
:include: restart
|
||||
|
||||
And finally in case of the fatal ``IllegalArgumentException`` the child will be
|
||||
terminated by the supervisor:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingTestBase.java
|
||||
.. includecode:: code/docs/actor/FaultHandlingTestBase.java
|
||||
:include: stop
|
||||
|
||||
Up to now the supervisor was completely unaffected by the child’s failure,
|
||||
because the directives set did handle it. In case of an ``Exception``, this is not
|
||||
true anymore and the supervisor escalates the failure.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingTestBase.java
|
||||
.. includecode:: code/docs/actor/FaultHandlingTestBase.java
|
||||
:include: escalate-kill
|
||||
|
||||
The supervisor itself is supervised by the top-level actor provided by the
|
||||
|
|
@ -125,12 +125,12 @@ child not to survive this failure.
|
|||
In case this is not desired (which depends on the use case), we need to use a
|
||||
different supervisor which overrides this behavior.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingTestBase.java
|
||||
.. includecode:: code/docs/actor/FaultHandlingTestBase.java
|
||||
:include: supervisor2
|
||||
|
||||
With this parent, the child survives the escalated restart, as demonstrated in
|
||||
the last test:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingTestBase.java
|
||||
.. includecode:: code/docs/actor/FaultHandlingTestBase.java
|
||||
:include: escalate-restart
|
||||
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ using a small well-defined set of methods. One way to achieve this is to
|
|||
assemble all mutable state in a superclass which keeps it private and offers
|
||||
protected methods for mutating it.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocTestBase.java#imports-data
|
||||
.. includecode:: code/docs/actor/FSMDocTestBase.java#imports-data
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocTestBase.java#base
|
||||
.. includecode:: code/docs/actor/FSMDocTestBase.java#base
|
||||
|
||||
The benefit of this approach is that state changes can be acted upon in one
|
||||
central place, which makes it impossible to forget inserting code for reacting
|
||||
|
|
@ -50,15 +50,15 @@ The base class shown above is designed to support a similar example as for the
|
|||
Scala FSM documentation: an actor which receives and queues messages, to be
|
||||
delivered in batches to a configurable target actor. The messages involved are:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocTestBase.java#data
|
||||
.. includecode:: code/docs/actor/FSMDocTestBase.java#data
|
||||
|
||||
This actor has only the two states ``IDLE`` and ``ACTIVE``, making their
|
||||
handling quite straight-forward in the concrete actor derived from the base
|
||||
class:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocTestBase.java#imports-actor
|
||||
.. includecode:: code/docs/actor/FSMDocTestBase.java#imports-actor
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocTestBase.java#actor
|
||||
.. includecode:: code/docs/actor/FSMDocTestBase.java#actor
|
||||
|
||||
The trick here is to factor out common functionality like :meth:`whenUnhandled`
|
||||
and :meth:`transition` in order to obtain a few well-defined points for
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ which is very similar to a ``java.util.concurrent.Executor``. if you have an ``A
|
|||
it will use its default dispatcher as the ``ExecutionContext``, or you can use the factory methods provided
|
||||
by the ``ExecutionContexts`` class to wrap ``Executors`` and ``ExecutorServices``, or even create your own.
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: imports1,imports7,diy-execution-context
|
||||
|
||||
Use with Actors
|
||||
|
|
@ -30,7 +30,7 @@ which only works if the original sender was an ``UntypedActor``) and the second
|
|||
Using the ``ActorRef``\'s ``ask`` method to send a message will return a Future.
|
||||
To wait for and retrieve the actual result the simplest method is:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: imports1,ask-blocking
|
||||
|
||||
This will cause the current thread to block and wait for the ``UntypedActor`` to 'complete' the ``Future`` with it's reply.
|
||||
|
|
@ -47,7 +47,7 @@ A common use case within Akka is to have some computation performed concurrently
|
|||
the extra utility of an ``UntypedActor``. If you find yourself creating a pool of ``UntypedActor``\s for the sole reason
|
||||
of performing a calculation in parallel, there is an easier (and faster) way:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: imports2,future-eval
|
||||
|
||||
In the above code the block passed to ``future`` will be executed by the default ``Dispatcher``,
|
||||
|
|
@ -57,12 +57,12 @@ and we also avoid the overhead of managing an ``UntypedActor``.
|
|||
|
||||
You can also create already completed Futures using the ``Futures`` class, which can be either successes:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: successful
|
||||
|
||||
Or failures:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: failed
|
||||
|
||||
Functional Futures
|
||||
|
|
@ -78,7 +78,7 @@ The first method for working with ``Future`` functionally is ``map``. This metho
|
|||
some operation on the result of the ``Future``, and returning a new result.
|
||||
The return value of the ``map`` method is another ``Future`` that will contain the new result:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: imports2,map
|
||||
|
||||
In this example we are joining two strings together within a Future. Instead of waiting for f1 to complete,
|
||||
|
|
@ -92,7 +92,7 @@ Something to note when using these methods: if the ``Future`` is still being pro
|
|||
it will be the completing thread that actually does the work.
|
||||
If the ``Future`` is already complete though, it will be run in our current thread. For example:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: map2
|
||||
|
||||
The original ``Future`` will take at least 0.1 second to execute now, which means it is still being processed at
|
||||
|
|
@ -101,7 +101,7 @@ by the dispatcher when the result is ready.
|
|||
|
||||
If we do the opposite:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: map3
|
||||
|
||||
Our little string has been processed long before our 0.1 second sleep has finished. Because of this,
|
||||
|
|
@ -112,7 +112,7 @@ Normally this works quite well as it means there is very little overhead to runn
|
|||
If there is a possibility of the function taking a non-trivial amount of time to process it might be better
|
||||
to have this done concurrently, and for that we use ``flatMap``:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: flat-map
|
||||
|
||||
Now our second Future is executed concurrently as well. This technique can also be used to combine the results
|
||||
|
|
@ -120,7 +120,7 @@ of several Futures into a single calculation, which will be better explained in
|
|||
|
||||
If you need to do conditional propagation, you can use ``filter``:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: filter
|
||||
|
||||
Composing Futures
|
||||
|
|
@ -129,7 +129,7 @@ Composing Futures
|
|||
It is very often desirable to be able to combine different Futures with each other,
|
||||
below are some examples on how that can be done in a non-blocking fashion.
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: imports3,sequence
|
||||
|
||||
To better explain what happened in the example, ``Future.sequence`` is taking the ``Iterable<Future<Integer>>``
|
||||
|
|
@ -139,7 +139,7 @@ and we aggregate the sum of the ``Iterable``.
|
|||
The ``traverse`` method is similar to ``sequence``, but it takes a sequence of ``A``s and applies a function from ``A`` to ``Future<B>``
|
||||
and returns a ``Future<Iterable<B>>``, enabling parallel ``map`` over the sequence, if you use ``Futures.future`` to create the ``Future``.
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: imports4,traverse
|
||||
|
||||
It's as simple as that!
|
||||
|
|
@ -150,7 +150,7 @@ and the type of the futures and returns something with the same type as the star
|
|||
and then applies the function to all elements in the sequence of futures, non-blockingly,
|
||||
the execution will be started when the last of the Futures is completed.
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: imports5,fold
|
||||
|
||||
That's all it takes!
|
||||
|
|
@ -160,7 +160,7 @@ If the sequence passed to ``fold`` is empty, it will return the start-value, in
|
|||
In some cases you don't have a start-value and you're able to use the value of the first completing Future
|
||||
in the sequence as the start-value, you can use ``reduce``, it works like this:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: imports6,reduce
|
||||
|
||||
Same as with ``fold``, the execution will be started when the last of the Futures is completed, you can also parallelize
|
||||
|
|
@ -174,13 +174,13 @@ Callbacks
|
|||
Sometimes you just want to listen to a ``Future`` being completed, and react to that not by creating a new Future, but by side-effecting.
|
||||
For this Akka supports ``onComplete``, ``onSuccess`` and ``onFailure``, of which the latter two are specializations of the first.
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: onSuccess
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: onFailure
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: onComplete
|
||||
|
||||
Ordering
|
||||
|
|
@ -192,7 +192,7 @@ But there's a solution! And it's name is ``andThen``, and it creates a new Futur
|
|||
the specified callback, a Future that will have the same result as the Future it's called on,
|
||||
which allows for ordering like in the following sample:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: and-then
|
||||
|
||||
Auxiliary methods
|
||||
|
|
@ -201,13 +201,13 @@ Auxiliary methods
|
|||
``Future`` ``fallbackTo`` combines 2 Futures into a new ``Future``, and will hold the successful value of the second ``Future``
|
||||
if the first ``Future`` fails.
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: fallback-to
|
||||
|
||||
You can also combine two Futures into a new ``Future`` that will hold a tuple of the two Futures successful results,
|
||||
using the ``zip`` operation.
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: zip
|
||||
|
||||
Exceptions
|
||||
|
|
@ -221,7 +221,7 @@ calling ``Await.result`` will cause it to be thrown again so it can be handled p
|
|||
It is also possible to handle an ``Exception`` by returning a different result.
|
||||
This is done with the ``recover`` method. For example:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: recover
|
||||
|
||||
In this example, if the actor replied with a ``akka.actor.Status.Failure`` containing the ``ArithmeticException``,
|
||||
|
|
@ -232,6 +232,6 @@ it will behave as if we hadn't used the ``recover`` method.
|
|||
You can also use the ``recoverWith`` method, which has the same relationship to ``recover`` as ``flatMap`` has to ``map``,
|
||||
and is use like this:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocTestBase.java
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: try-recover
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ How to Log
|
|||
Create a ``LoggingAdapter`` and use the ``error``, ``warning``, ``info``, or ``debug`` methods,
|
||||
as illustrated in this example:
|
||||
|
||||
.. includecode:: code/akka/docs/event/LoggingDocTestBase.java
|
||||
.. includecode:: code/docs/event/LoggingDocTestBase.java
|
||||
:include: imports,my-actor
|
||||
|
||||
The first parameter to ``Logging.getLogger`` could also be any
|
||||
|
|
@ -33,7 +33,7 @@ placeholders results in a warning being appended to the log statement (i.e. on
|
|||
the same line with the same severity). You may pass a Java array as the only
|
||||
substitution argument to have its elements be treated individually:
|
||||
|
||||
.. includecode:: code/akka/docs/event/LoggingDocTestBase.java#array
|
||||
.. includecode:: code/docs/event/LoggingDocTestBase.java#array
|
||||
|
||||
The Java :class:`Class` of the log source is also included in the generated
|
||||
:class:`LogEvent`. In case of a simple string this is replaced with a “marker”
|
||||
|
|
@ -170,7 +170,7 @@ event handler available in the 'akka-slf4j' module.
|
|||
|
||||
Example of creating a listener:
|
||||
|
||||
.. includecode:: code/akka/docs/event/LoggingDocTestBase.java
|
||||
.. includecode:: code/docs/event/LoggingDocTestBase.java
|
||||
:include: imports,imports-listener,my-event-listener
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -82,11 +82,11 @@ The "app" in this case refers to the name of the ``ActorSystem`` (only showing d
|
|||
Logical path lookup is supported on the node you are on, i.e. to use the
|
||||
actor created above you would do the following:
|
||||
|
||||
.. includecode:: code/akka/docs/remoting/RemoteActorExample.java#localNodeActor
|
||||
.. includecode:: code/docs/remoting/RemoteActorExample.java#localNodeActor
|
||||
|
||||
This will obtain an ``ActorRef`` on a remote node:
|
||||
|
||||
.. includecode:: code/akka/docs/remoting/RemoteActorExample.java#remoteNodeActor
|
||||
.. includecode:: code/docs/remoting/RemoteActorExample.java#remoteNodeActor
|
||||
|
||||
As you can see from the example above the following pattern is used to find an ``ActorRef`` on a remote node::
|
||||
|
||||
|
|
@ -103,15 +103,15 @@ precedence.
|
|||
|
||||
With these imports:
|
||||
|
||||
.. includecode:: code/akka/docs/remoting/RemoteDeploymentDocTestBase.java#import
|
||||
.. includecode:: code/docs/remoting/RemoteDeploymentDocTestBase.java#import
|
||||
|
||||
and a remote address like this:
|
||||
|
||||
.. includecode:: code/akka/docs/remoting/RemoteDeploymentDocTestBase.java#make-address
|
||||
.. includecode:: code/docs/remoting/RemoteDeploymentDocTestBase.java#make-address
|
||||
|
||||
you can advise the system to create a child on that remote node like so:
|
||||
|
||||
.. includecode:: code/akka/docs/remoting/RemoteDeploymentDocTestBase.java#deploy
|
||||
.. includecode:: code/docs/remoting/RemoteDeploymentDocTestBase.java#deploy
|
||||
|
||||
Serialization
|
||||
^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -21,17 +21,17 @@ Routers In Action
|
|||
|
||||
This is an example of how to create a router that is defined in configuration:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/routing/RouterViaConfigExample.scala#config
|
||||
.. includecode:: ../scala/code/docs/routing/RouterViaConfigExample.scala#config
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/RouterViaConfigExample.java#configurableRouting
|
||||
.. includecode:: code/docs/jrouting/RouterViaConfigExample.java#configurableRouting
|
||||
|
||||
This is an example of how to programmatically create a router and set the number of routees it should create:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/RouterViaProgramExample.java#programmaticRoutingNrOfInstances
|
||||
.. includecode:: code/docs/jrouting/RouterViaProgramExample.java#programmaticRoutingNrOfInstances
|
||||
|
||||
You can also give the router already created routees as in:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/RouterViaProgramExample.java#programmaticRoutingRoutees
|
||||
.. includecode:: code/docs/jrouting/RouterViaProgramExample.java#programmaticRoutingRoutees
|
||||
|
||||
It should be noted that no actor factory or class needs to be provided in this
|
||||
case, as the ``Router`` will not create any children on its own (which is not
|
||||
|
|
@ -65,7 +65,7 @@ configuration in a :class:`RemoteRouterConfig`, attaching the remote addresses o
|
|||
the nodes to deploy to. Naturally, this requires your to include the
|
||||
``akka-remote`` module on your classpath:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/RouterViaProgramExample.java#remoteRoutees
|
||||
.. includecode:: code/docs/jrouting/RouterViaProgramExample.java#remoteRoutees
|
||||
|
||||
How Routing is Designed within Akka
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -95,9 +95,9 @@ deterministic fashion. Since each actor knows its own external representation
|
|||
as well as that of its parent, the routees decide where replies should be sent
|
||||
when reacting to a message:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/RouterViaProgramExample.java#reply-with-parent
|
||||
.. includecode:: code/docs/jrouting/RouterViaProgramExample.java#reply-with-parent
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/RouterViaProgramExample.java#reply-with-self
|
||||
.. includecode:: code/docs/jrouting/RouterViaProgramExample.java#reply-with-self
|
||||
|
||||
It is apparent now why routing needs to be enabled in code rather than being
|
||||
possible to “bolt on” later: whether or not an actor is routed means a change
|
||||
|
|
@ -121,7 +121,7 @@ not have an effect on the number of actors in the pool.
|
|||
|
||||
Setting the strategy is easily done:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/CustomRouterDocTestBase.java
|
||||
.. includecode:: code/docs/jrouting/CustomRouterDocTestBase.java
|
||||
:include: supervision
|
||||
|
||||
Another potentially useful approach is to give the router the same strategy as
|
||||
|
|
@ -140,18 +140,18 @@ Router usage
|
|||
In this section we will describe how to use the different router types.
|
||||
First we need to create some actors that will be used in the examples:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/PrintlnActor.java#printlnActor
|
||||
.. includecode:: code/docs/jrouting/PrintlnActor.java#printlnActor
|
||||
|
||||
and
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/FibonacciActor.java#fibonacciActor
|
||||
.. includecode:: code/docs/jrouting/FibonacciActor.java#fibonacciActor
|
||||
|
||||
RoundRobinRouter
|
||||
****************
|
||||
Routes in a `round-robin <http://en.wikipedia.org/wiki/Round-robin>`_ fashion to its routees.
|
||||
Code example:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/ParentActor.java#roundRobinRouter
|
||||
.. includecode:: code/docs/jrouting/ParentActor.java#roundRobinRouter
|
||||
|
||||
When run you should see a similar output to this:
|
||||
|
||||
|
|
@ -180,7 +180,7 @@ the message it receives to this routee.
|
|||
This procedure will happen each time it receives a message.
|
||||
Code example:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/ParentActor.java#randomRouter
|
||||
.. includecode:: code/docs/jrouting/ParentActor.java#randomRouter
|
||||
|
||||
When run you should see a similar output to this:
|
||||
|
||||
|
|
@ -213,14 +213,14 @@ The selection is done in this order:
|
|||
|
||||
Code example:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/ParentActor.java#smallestMailboxRouter
|
||||
.. includecode:: code/docs/jrouting/ParentActor.java#smallestMailboxRouter
|
||||
|
||||
BroadcastRouter
|
||||
***************
|
||||
A broadcast router forwards the message it receives to *all* its routees.
|
||||
Code example:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/ParentActor.java#broadcastRouter
|
||||
.. includecode:: code/docs/jrouting/ParentActor.java#broadcastRouter
|
||||
|
||||
When run you should see a similar output to this:
|
||||
|
||||
|
|
@ -240,7 +240,7 @@ The ScatterGatherFirstCompletedRouter will send the message on to all its routee
|
|||
It then waits for first result it gets back. This result will be sent back to original sender.
|
||||
Code example:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/ParentActor.java#scatterGatherFirstCompletedRouter
|
||||
.. includecode:: code/docs/jrouting/ParentActor.java#scatterGatherFirstCompletedRouter
|
||||
|
||||
When run you should see this:
|
||||
|
||||
|
|
@ -272,16 +272,16 @@ of routees dynamically.
|
|||
|
||||
This is an example of how to create a resizable router that is defined in configuration:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/routing/RouterViaConfigExample.scala#config-resize
|
||||
.. includecode:: ../scala/code/docs/routing/RouterViaConfigExample.scala#config-resize
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/RouterViaConfigExample.java#configurableRoutingWithResizer
|
||||
.. includecode:: code/docs/jrouting/RouterViaConfigExample.java#configurableRoutingWithResizer
|
||||
|
||||
Several more configuration options are available and described in ``akka.actor.deployment.default.resizer``
|
||||
section of the reference :ref:`configuration`.
|
||||
|
||||
This is an example of how to programmatically create a resizable router:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/RouterViaProgramExample.java#programmaticRoutingWithResizer
|
||||
.. includecode:: code/docs/jrouting/RouterViaProgramExample.java#programmaticRoutingWithResizer
|
||||
|
||||
*It is also worth pointing out that if you define the ``router`` in the configuration file then this value
|
||||
will be used instead of any programmatically sent parameters.*
|
||||
|
|
@ -308,12 +308,12 @@ democrat related messages to the Democrat actor and all republican related messa
|
|||
|
||||
We begin with defining the class:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/CustomRouterDocTestBase.java#crRouter
|
||||
.. includecode:: code/docs/jrouting/CustomRouterDocTestBase.java#crRouter
|
||||
:exclude: crRoute
|
||||
|
||||
The next step is to implement the ``createCustomRoute`` method in the class just defined:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/CustomRouterDocTestBase.java#crRoute
|
||||
.. includecode:: code/docs/jrouting/CustomRouterDocTestBase.java#crRoute
|
||||
|
||||
As you can see above we start off by creating the routees and put them in a collection.
|
||||
|
||||
|
|
@ -322,12 +322,12 @@ It registers the routees internally and failing to call this method will
|
|||
cause a ``ActorInitializationException`` to be thrown when the router is used.
|
||||
Therefore always make sure to do the following in your custom router:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/CustomRouterDocTestBase.java#crRegisterRoutees
|
||||
.. includecode:: code/docs/jrouting/CustomRouterDocTestBase.java#crRegisterRoutees
|
||||
|
||||
The routing logic is where your magic sauce is applied. In our example it inspects the message types
|
||||
and forwards to the correct routee based on this:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/CustomRouterDocTestBase.java#crRoutingLogic
|
||||
.. includecode:: code/docs/jrouting/CustomRouterDocTestBase.java#crRoutingLogic
|
||||
|
||||
As you can see above what's returned in the ``CustomRoute`` function, which defines the mapping
|
||||
from incoming sender/message to a ``List`` of ``Destination(sender, routee)``.
|
||||
|
|
@ -338,11 +338,11 @@ For more information about how to alter the original sender we refer to the sour
|
|||
|
||||
All in all the custom router looks like this:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/CustomRouterDocTestBase.java#CustomRouter
|
||||
.. includecode:: code/docs/jrouting/CustomRouterDocTestBase.java#CustomRouter
|
||||
|
||||
If you are interested in how to use the VoteCountRouter it looks like this:
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/CustomRouterDocTestBase.java#crTest
|
||||
.. includecode:: code/docs/jrouting/CustomRouterDocTestBase.java#crTest
|
||||
|
||||
.. caution::
|
||||
|
||||
|
|
@ -391,5 +391,5 @@ the actor system’s default dispatcher. All standard routers allow setting this
|
|||
property in their constructor or factory method, custom routers have to
|
||||
implement the method in a suitable way.
|
||||
|
||||
.. includecode:: code/akka/docs/jrouting/CustomRouterDocTestBase.java#dispatchers
|
||||
.. includecode:: code/docs/jrouting/CustomRouterDocTestBase.java#dispatchers
|
||||
|
||||
|
|
|
|||
|
|
@ -25,13 +25,13 @@ scheduled operation.
|
|||
Some examples
|
||||
-------------
|
||||
|
||||
.. includecode:: code/akka/docs/actor/SchedulerDocTestBase.java
|
||||
.. includecode:: code/docs/actor/SchedulerDocTestBase.java
|
||||
:include: imports1,schedule-one-off-message
|
||||
|
||||
.. includecode:: code/akka/docs/actor/SchedulerDocTestBase.java
|
||||
.. includecode:: code/docs/actor/SchedulerDocTestBase.java
|
||||
:include: schedule-one-off-thunk
|
||||
|
||||
.. includecode:: code/akka/docs/actor/SchedulerDocTestBase.java
|
||||
.. includecode:: code/docs/actor/SchedulerDocTestBase.java
|
||||
:include: imports1,imports2,schedule-recurring
|
||||
|
||||
From ``akka.actor.ActorSystem``
|
||||
|
|
|
|||
|
|
@ -21,12 +21,12 @@ For Akka to know which ``Serializer`` to use for what, you need edit your :ref:`
|
|||
in the "akka.actor.serializers"-section you bind names to implementations of the ``akka.serialization.Serializer``
|
||||
you wish to use, like this:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/serialization/SerializationDocSpec.scala#serialize-serializers-config
|
||||
.. includecode:: ../scala/code/docs/serialization/SerializationDocSpec.scala#serialize-serializers-config
|
||||
|
||||
After you've bound names to different implementations of ``Serializer`` you need to wire which classes
|
||||
should be serialized using which ``Serializer``, this is done in the "akka.actor.serialization-bindings"-section:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/serialization/SerializationDocSpec.scala#serialization-bindings-config
|
||||
.. includecode:: ../scala/code/docs/serialization/SerializationDocSpec.scala#serialization-bindings-config
|
||||
|
||||
You only need to specify the name of an interface or abstract base class of the
|
||||
messages. In case of ambiguity, i.e. the message implements several of the
|
||||
|
|
@ -53,7 +53,7 @@ Verification
|
|||
|
||||
If you want to verify that your messages are serializable you can enable the following config option:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/serialization/SerializationDocSpec.scala#serialize-messages-config
|
||||
.. includecode:: ../scala/code/docs/serialization/SerializationDocSpec.scala#serialize-messages-config
|
||||
|
||||
.. warning::
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ If you want to verify that your messages are serializable you can enable the fol
|
|||
|
||||
If you want to verify that your ``Props`` are serializable you can enable the following config option:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/serialization/SerializationDocSpec.scala#serialize-creators-config
|
||||
.. includecode:: ../scala/code/docs/serialization/SerializationDocSpec.scala#serialize-creators-config
|
||||
|
||||
.. warning::
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ Programmatic
|
|||
If you want to programmatically serialize/deserialize using Akka Serialization,
|
||||
here's some examples:
|
||||
|
||||
.. includecode:: code/akka/docs/serialization/SerializationDocTestBase.java
|
||||
.. includecode:: code/docs/serialization/SerializationDocTestBase.java
|
||||
:include: imports,programmatic
|
||||
|
||||
For more information, have a look at the ``ScalaDoc`` for ``akka.serialization._``
|
||||
|
|
@ -93,7 +93,7 @@ Creating new Serializers
|
|||
First you need to create a class definition of your ``Serializer``,
|
||||
which is done by extending ``akka.serialization.JSerializer``, like this:
|
||||
|
||||
.. includecode:: code/akka/docs/serialization/SerializationDocTestBase.java
|
||||
.. includecode:: code/docs/serialization/SerializationDocTestBase.java
|
||||
:include: imports,my-own-serializer
|
||||
:exclude: ...
|
||||
|
||||
|
|
@ -106,7 +106,7 @@ Serializing ActorRefs
|
|||
All ActorRefs are serializable using JavaSerializer, but in case you are writing your own serializer,
|
||||
you might want to know how to serialize and deserialize them properly, here's the magic incantation:
|
||||
|
||||
.. includecode:: code/akka/docs/serialization/SerializationDocTestBase.java
|
||||
.. includecode:: code/docs/serialization/SerializationDocTestBase.java
|
||||
:include: imports,actorref-serializer
|
||||
|
||||
.. note::
|
||||
|
|
@ -131,7 +131,7 @@ address which shall be the recipient of the serialized information. Use
|
|||
:meth:`ActorRefProvider.getExternalAddressFor(remoteAddr)` to query the system
|
||||
for the appropriate address to use when sending to ``remoteAddr``:
|
||||
|
||||
.. includecode:: code/akka/docs/serialization/SerializationDocTestBase.java
|
||||
.. includecode:: code/docs/serialization/SerializationDocTestBase.java
|
||||
:include: external-address
|
||||
|
||||
This requires that you know at least which type of address will be supported by
|
||||
|
|
@ -144,7 +144,7 @@ There is a possible simplification available if you are just using the default
|
|||
:class:`NettyRemoteTransport` with the :meth:`RemoteActorRefProvider`, which is
|
||||
enabled by the fact that this combination has just a single remote address:
|
||||
|
||||
.. includecode:: code/akka/docs/serialization/SerializationDocTestBase.java
|
||||
.. includecode:: code/docs/serialization/SerializationDocTestBase.java
|
||||
:include: external-address-default
|
||||
|
||||
This solution has to be adapted once other providers are used (like the planned
|
||||
|
|
|
|||
|
|
@ -63,22 +63,22 @@ Here is an example of coordinating two simple counter UntypedActors so that they
|
|||
both increment together in coordinated transactions. If one of them was to fail
|
||||
to increment, the other would also fail.
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/Increment.java#class
|
||||
.. includecode:: code/docs/transactor/Increment.java#class
|
||||
:language: java
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/CoordinatedCounter.java#class
|
||||
.. includecode:: code/docs/transactor/CoordinatedCounter.java#class
|
||||
:language: java
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocTest.java#imports
|
||||
.. includecode:: code/docs/transactor/TransactorDocTest.java#imports
|
||||
:language: java
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocTest.java#coordinated-example
|
||||
.. includecode:: code/docs/transactor/TransactorDocTest.java#coordinated-example
|
||||
:language: java
|
||||
|
||||
To start a new coordinated transaction that you will also participate in, create
|
||||
a ``Coordinated`` object, passing in a ``Timeout``:
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocTest.java#create-coordinated
|
||||
.. includecode:: code/docs/transactor/TransactorDocTest.java#create-coordinated
|
||||
:language: java
|
||||
|
||||
To start a coordinated transaction that you won't participate in yourself you
|
||||
|
|
@ -86,7 +86,7 @@ can create a ``Coordinated`` object with a message and send it directly to an
|
|||
actor. The recipient of the message will be the first member of the coordination
|
||||
set:
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocTest.java#send-coordinated
|
||||
.. includecode:: code/docs/transactor/TransactorDocTest.java#send-coordinated
|
||||
:language: java
|
||||
|
||||
To include another actor in the same coordinated transaction that you've created
|
||||
|
|
@ -94,13 +94,13 @@ or received, use the ``coordinate`` method on that object. This will increment
|
|||
the number of parties involved by one and create a new ``Coordinated`` object to
|
||||
be sent.
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocTest.java#include-coordinated
|
||||
.. includecode:: code/docs/transactor/TransactorDocTest.java#include-coordinated
|
||||
:language: java
|
||||
|
||||
To enter the coordinated transaction use the atomic method of the coordinated
|
||||
object, passing in a ``java.lang.Runnable``.
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/Coordinator.java#coordinated-atomic
|
||||
.. includecode:: code/docs/transactor/Coordinator.java#coordinated-atomic
|
||||
:language: java
|
||||
|
||||
The coordinated transaction will wait for the other transactions before
|
||||
|
|
@ -124,7 +124,7 @@ coordinating transactions, using the explicit coordination described above.
|
|||
Here's an example of a simple untyped transactor that will join a coordinated
|
||||
transaction:
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/Counter.java#class
|
||||
.. includecode:: code/docs/transactor/Counter.java#class
|
||||
:language: java
|
||||
|
||||
You could send this Counter transactor a ``Coordinated(Increment)`` message. If
|
||||
|
|
@ -140,7 +140,7 @@ to easily coordinate with other transactors.
|
|||
Here's an example of coordinating an increment, using an untyped transactor,
|
||||
similar to the explicitly coordinated example above.
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/FriendlyCounter.java#class
|
||||
.. includecode:: code/docs/transactor/FriendlyCounter.java#class
|
||||
:language: java
|
||||
|
||||
To execute directly before or after the coordinated transaction, override the
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ The tools of the trade
|
|||
Before we create our first Typed Actor we should first go through the tools that we have at our disposal,
|
||||
it's located in ``akka.actor.TypedActor``.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/TypedActorDocTestBase.java
|
||||
:include: typed-actor-extension-tools
|
||||
|
||||
.. warning::
|
||||
|
|
@ -55,37 +55,37 @@ To create a Typed Actor you need to have one or more interfaces, and one impleme
|
|||
|
||||
Our example interface:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/TypedActorDocTestBase.java
|
||||
:include: imports,typed-actor-iface
|
||||
:exclude: typed-actor-iface-methods
|
||||
|
||||
Our example implementation of that interface:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/TypedActorDocTestBase.java
|
||||
:include: imports,typed-actor-impl
|
||||
:exclude: typed-actor-impl-methods
|
||||
|
||||
The most trivial way of creating a Typed Actor instance
|
||||
of our ``Squarer``:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/TypedActorDocTestBase.java
|
||||
:include: typed-actor-create1
|
||||
|
||||
First type is the type of the proxy, the second type is the type of the implementation.
|
||||
If you need to call a specific constructor you do it like this:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/TypedActorDocTestBase.java
|
||||
:include: typed-actor-create2
|
||||
|
||||
Since you supply a ``Props``, you can specify which dispatcher to use, what the default timeout should be used and more.
|
||||
Now, our ``Squarer`` doesn't have any methods, so we'd better add those.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/TypedActorDocTestBase.java
|
||||
:include: imports,typed-actor-iface
|
||||
|
||||
Alright, now we've got some methods we can call, but we need to implement those in ``SquarerImpl``.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/TypedActorDocTestBase.java
|
||||
:include: imports,typed-actor-impl
|
||||
|
||||
Excellent, now we have an interface and an implementation of that interface,
|
||||
|
|
@ -113,7 +113,7 @@ we *strongly* recommend that parameters passed are immutable.
|
|||
One-way message send
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/TypedActorDocTestBase.java
|
||||
:include: typed-actor-call-oneway
|
||||
|
||||
As simple as that! The method will be executed on another thread; asynchronously.
|
||||
|
|
@ -121,13 +121,13 @@ As simple as that! The method will be executed on another thread; asynchronously
|
|||
Request-reply message send
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/TypedActorDocTestBase.java
|
||||
:include: typed-actor-call-option
|
||||
|
||||
This will block for as long as the timeout that was set in the ``Props`` of the Typed Actor,
|
||||
if needed. It will return ``None`` if a timeout occurs.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/TypedActorDocTestBase.java
|
||||
:include: typed-actor-call-strict
|
||||
|
||||
This will block for as long as the timeout that was set in the ``Props` of the Typed Actor,
|
||||
|
|
@ -136,7 +136,7 @@ if needed. It will throw a ``java.util.concurrent.TimeoutException`` if a timeou
|
|||
Request-reply-with-future message send
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/TypedActorDocTestBase.java
|
||||
:include: typed-actor-call-future
|
||||
|
||||
This call is asynchronous, and the Future returned can be used for asynchronous composition.
|
||||
|
|
@ -146,12 +146,12 @@ Stopping Typed Actors
|
|||
|
||||
Since Akka's Typed Actors are backed by Akka Actors they must be stopped when they aren't needed anymore.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/TypedActorDocTestBase.java
|
||||
:include: typed-actor-stop
|
||||
|
||||
This asynchronously stops the Typed Actor associated with the specified proxy ASAP.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/TypedActorDocTestBase.java
|
||||
:include: typed-actor-poisonpill
|
||||
|
||||
This asynchronously stops the Typed Actor associated with the specified proxy
|
||||
|
|
@ -204,4 +204,4 @@ Lookup & Remoting
|
|||
|
||||
Since ``TypedActors`` are backed by ``Akka Actors``, you can use ``actorFor`` together with ``typedActorOf`` to proxy ``ActorRefs`` potentially residing on remote nodes.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocTestBase.java#typed-actor-remote
|
||||
.. includecode:: code/docs/actor/TypedActorDocTestBase.java#typed-actor-remote
|
||||
|
|
@ -36,7 +36,7 @@ Actor in Java are implemented by extending the ``UntypedActor`` class and implem
|
|||
|
||||
Here is an example:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/MyUntypedActor.java#my-untyped-actor
|
||||
.. includecode:: code/docs/actor/MyUntypedActor.java#my-untyped-actor
|
||||
|
||||
Props
|
||||
-----
|
||||
|
|
@ -44,7 +44,7 @@ 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
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#creating-props-config
|
||||
|
||||
|
||||
Creating Actors with Props
|
||||
|
|
@ -52,13 +52,13 @@ 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
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#creating-props
|
||||
|
||||
|
||||
Creating Actors with default constructor
|
||||
----------------------------------------
|
||||
|
||||
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java
|
||||
:include: imports,system-actorOf
|
||||
|
||||
The call to :meth:`actorOf` returns an instance of ``ActorRef``. This is a handle to
|
||||
|
|
@ -75,7 +75,7 @@ how the supervisor hierarchy is arranged. When using the context the current act
|
|||
will be supervisor of the created child actor. When using the system it will be
|
||||
a top level actor, that is supervised by the system (internal guardian actor).
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FirstUntypedActor.java#context-actorOf
|
||||
.. includecode:: code/docs/actor/FirstUntypedActor.java#context-actorOf
|
||||
|
||||
The name parameter is optional, but you should preferably name your actors, since
|
||||
that is used in log messages and for identifying actors. The name must not be empty
|
||||
|
|
@ -110,7 +110,7 @@ in which you can create the Actor in any way you like.
|
|||
|
||||
Here is an example:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#creating-constructor
|
||||
.. includecode:: code/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.
|
||||
|
|
@ -144,7 +144,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/UntypedActorDocTestBase.java#lifecycle-callbacks
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#lifecycle-callbacks
|
||||
|
||||
The implementations shown above are the defaults provided by the :class:`UntypedActor`
|
||||
class.
|
||||
|
|
@ -163,7 +163,7 @@ termination (see `Stopping Actors`_). This service is provided by the
|
|||
Registering a monitor is easy (see fourth line, the rest is for demonstrating
|
||||
the whole functionality):
|
||||
|
||||
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#watch
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#watch
|
||||
|
||||
It should be noted that the :class:`Terminated` message is generated
|
||||
independent of the order in which registration and termination occur.
|
||||
|
|
@ -279,7 +279,7 @@ convention.
|
|||
|
||||
Here is an example of an immutable message:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ImmutableMessage.java#immutable-message
|
||||
.. includecode:: code/docs/actor/ImmutableMessage.java#immutable-message
|
||||
|
||||
|
||||
Send messages
|
||||
|
|
@ -332,9 +332,9 @@ Ask: Send-And-Receive-Future
|
|||
The ``ask`` pattern involves actors as well as futures, hence it is offered as
|
||||
a use pattern rather than a method on :class:`ActorRef`:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#import-askPipe
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#import-askPipe
|
||||
|
||||
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#ask-pipe
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#ask-pipe
|
||||
|
||||
This example demonstrates ``ask`` together with the ``pipe`` pattern on
|
||||
futures, because this is likely to be a common combination. Please note that
|
||||
|
|
@ -355,7 +355,7 @@ To complete the future with an exception you need send a Failure message to the
|
|||
This is *not done automatically* when an actor throws an exception while processing a
|
||||
message.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#reply-exception
|
||||
.. includecode:: code/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; this will complete the
|
||||
|
|
@ -399,7 +399,7 @@ an abstract method on the ``UntypedActor`` base class that needs to be defined.
|
|||
|
||||
Here is an example:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/MyUntypedActor.java#my-untyped-actor
|
||||
.. includecode:: code/docs/actor/MyUntypedActor.java#my-untyped-actor
|
||||
|
||||
An alternative to using if-instanceof checks is to use `Apache Commons MethodUtils
|
||||
<http://commons.apache.org/beanutils/api/org/apache/commons/beanutils/MethodUtils.html#invokeMethod(java.lang.Object,%20java.lang.String,%20java.lang.Object)>`_
|
||||
|
|
@ -432,7 +432,7 @@ received within a certain time. To receive this timeout you have to set the
|
|||
``receiveTimeout`` property and declare handing for the ReceiveTimeout
|
||||
message.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/MyReceivedTimeoutUntypedActor.java#receive-timeout
|
||||
.. includecode:: code/docs/actor/MyReceivedTimeoutUntypedActor.java#receive-timeout
|
||||
|
||||
.. _stopping-actors-java:
|
||||
|
||||
|
|
@ -494,7 +494,7 @@ in the mailbox.
|
|||
|
||||
Use it like this:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java
|
||||
:include: import-actors,poison-pill
|
||||
|
||||
Graceful Stop
|
||||
|
|
@ -503,7 +503,7 @@ Graceful Stop
|
|||
:meth:`gracefulStop` is useful if you need to wait for termination or compose ordered
|
||||
termination of several actors:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java
|
||||
:include: import-gracefulStop,gracefulStop
|
||||
|
||||
When ``gracefulStop()`` returns successfully, the actor’s ``postStop()`` hook
|
||||
|
|
@ -537,7 +537,7 @@ 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/UntypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java
|
||||
:include: import-procedure,hot-swap-actor
|
||||
|
||||
The ``become`` method is useful for many different things, such as to implement
|
||||
|
|
@ -545,7 +545,7 @@ a Finite State Machine (FSM).
|
|||
|
||||
Here is another little cute example of ``become`` and ``unbecome`` in action:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/UntypedActorSwapper.java#swapper
|
||||
.. includecode:: code/docs/actor/UntypedActorSwapper.java#swapper
|
||||
|
||||
Downgrade
|
||||
---------
|
||||
|
|
@ -567,7 +567,7 @@ through regular supervisor semantics.
|
|||
|
||||
Use it like this:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java
|
||||
:include: import-actors,kill
|
||||
|
||||
Actors and exceptions
|
||||
|
|
|
|||
|
|
@ -19,15 +19,15 @@ Connection
|
|||
ZeroMQ supports multiple connectivity patterns, each aimed to meet a different set of requirements. Currently, this module supports publisher-subscriber connections and connections based on dealers and routers. For connecting or accepting connections, a socket must be created.
|
||||
Sockets are always created using the ``akka.zeromq.ZeroMQExtension``, for example:
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocTestBase.java#pub-socket
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocTestBase.java#pub-socket
|
||||
|
||||
Above examples will create a ZeroMQ Publisher socket that is Bound to the port 1233 on localhost.
|
||||
|
||||
Similarly you can create a subscription socket, with a listener, that subscribes to all messages from the publisher using:
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocTestBase.java#sub-socket
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocTestBase.java#sub-socket
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocTestBase.java#listener-actor
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocTestBase.java#listener-actor
|
||||
|
||||
The following sub-sections describe the supported connection patterns and how they can be used in an Akka environment. However, for a comprehensive discussion of connection patterns, please refer to `ZeroMQ -- The Guide <http://zguide.zeromq.org/page:all>`_.
|
||||
|
||||
|
|
@ -43,18 +43,18 @@ When you're using zeromq pub/sub you should be aware that it needs multicast - c
|
|||
|
||||
An actor is subscribed to a topic as follows:
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocTestBase.java#sub-topic-socket
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocTestBase.java#sub-topic-socket
|
||||
|
||||
It is a prefix match so it is subscribed to all topics starting with ``foo.bar``. Note that if the given string is empty or
|
||||
``Subscribe.all()`` is used, the actor is subscribed to all topics.
|
||||
|
||||
To unsubscribe from a topic you do the following:
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocTestBase.java#unsub-topic-socket
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocTestBase.java#unsub-topic-socket
|
||||
|
||||
To publish messages to a topic you must use two Frames with the topic in the first frame.
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocTestBase.java#pub-topic
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocTestBase.java#pub-topic
|
||||
|
||||
Pub-Sub in Action
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -64,22 +64,22 @@ The following example illustrates one publisher with two subscribers.
|
|||
The publisher monitors current heap usage and system load and periodically publishes ``Heap`` events on the ``"health.heap"`` topic
|
||||
and ``Load`` events on the ``"health.load"`` topic.
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocTestBase.java#health
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocTestBase.java#health
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocTestBase.java#health2
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocTestBase.java#health2
|
||||
|
||||
Let's add one subscriber that logs the information. It subscribes to all topics starting with ``"health"``, i.e. both ``Heap`` and
|
||||
``Load`` events.
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocTestBase.java#logger
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocTestBase.java#logger
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocTestBase.java#logger2
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocTestBase.java#logger2
|
||||
|
||||
Another subscriber keep track of used heap and warns if too much heap is used. It only subscribes to ``Heap`` events.
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocTestBase.java#alerter
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocTestBase.java#alerter
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocTestBase.java#alerter2
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocTestBase.java#alerter2
|
||||
|
||||
Router-Dealer Connection
|
||||
------------------------
|
||||
|
|
@ -90,7 +90,7 @@ With those socket types you can build your own reliable pub sub broker that uses
|
|||
|
||||
To create a Router socket that has a high watermark configured, you would do:
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocTestBase.java#high-watermark
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocTestBase.java#high-watermark
|
||||
|
||||
The akka-zeromq module accepts most if not all the available configuration options for a zeromq socket.
|
||||
|
||||
|
|
|
|||
|
|
@ -52,17 +52,17 @@ you need.
|
|||
In the configuration of the dispatcher you specify the fully qualified class name
|
||||
of the mailbox:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/mailbox/DurableMailboxDocSpec.scala
|
||||
.. includecode:: code/docs/actor/mailbox/DurableMailboxDocSpec.scala
|
||||
:include: dispatcher-config
|
||||
|
||||
Here is an example of how to create an actor with a durable dispatcher, in Scala:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/mailbox/DurableMailboxDocSpec.scala
|
||||
.. includecode:: code/docs/actor/mailbox/DurableMailboxDocSpec.scala
|
||||
:include: imports,dispatcher-config-use
|
||||
|
||||
Corresponding example in Java:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/mailbox/DurableMailboxDocTestBase.java
|
||||
.. includecode:: code/docs/actor/mailbox/DurableMailboxDocTestBase.java
|
||||
:include: imports,dispatcher-config-use
|
||||
|
||||
You can also configure and tune the file-based durable mailbox. This is done in
|
||||
|
|
@ -82,14 +82,14 @@ envelope that needs to be stored. As a help utility you can mixin DurableMessage
|
|||
to serialize and deserialize the envelope using the ordinary :ref:`serialization-scala`
|
||||
mechanism. This optional and you may store the envelope data in any way you like.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/mailbox/DurableMailboxDocSpec.scala
|
||||
.. includecode:: code/docs/actor/mailbox/DurableMailboxDocSpec.scala
|
||||
:include: custom-mailbox
|
||||
|
||||
To facilitate testing of a durable mailbox you may use ``DurableMailboxSpec`` as base class.
|
||||
It implements a few basic tests and helps you setup the a fixture. More tests can be
|
||||
added in concrete subclass like this:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/mailbox/DurableMailboxDocSpec.scala
|
||||
.. includecode:: code/docs/actor/mailbox/DurableMailboxDocSpec.scala
|
||||
:include: custom-mailbox-test
|
||||
|
||||
You find DurableMailboxDocSpec in ``akka-mailboxes-common-test-2.1-SNAPSHOT.jar``.
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ along with the implementation of how the messages should be processed.
|
|||
|
||||
Here is an example:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala
|
||||
:include: imports1,my-actor
|
||||
|
||||
Please note that the Akka Actor ``receive`` message loop is exhaustive, which is
|
||||
|
|
@ -52,7 +52,7 @@ published to the ``ActorSystem``'s ``EventStream``.
|
|||
Creating Actors with default constructor
|
||||
----------------------------------------
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala
|
||||
:include: imports2,system-actorOf
|
||||
|
||||
The call to :meth:`actorOf` returns an instance of ``ActorRef``. This is a handle to
|
||||
|
|
@ -69,7 +69,7 @@ how the supervisor hierarchy is arranged. When using the context the current act
|
|||
will be supervisor of the created child actor. When using the system it will be
|
||||
a top level actor, that is supervised by the system (internal guardian actor).
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#context-actorOf
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#context-actorOf
|
||||
|
||||
The name parameter is optional, but you should preferably name your actors, since
|
||||
that is used in log messages and for identifying actors. The name must not be empty
|
||||
|
|
@ -103,7 +103,7 @@ a call-by-name block in which you can create the Actor in any way you like.
|
|||
|
||||
Here is an example:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#creating-constructor
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#creating-constructor
|
||||
|
||||
|
||||
Props
|
||||
|
|
@ -112,7 +112,7 @@ 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/ActorDocSpec.scala#creating-props-config
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#creating-props-config
|
||||
|
||||
|
||||
Creating Actors with Props
|
||||
|
|
@ -120,7 +120,7 @@ Creating Actors with Props
|
|||
|
||||
Actors are created by passing in a ``Props`` instance into the ``actorOf`` factory method.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#creating-props
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#creating-props
|
||||
|
||||
|
||||
Creating Actors using anonymous classes
|
||||
|
|
@ -128,7 +128,7 @@ Creating Actors using anonymous classes
|
|||
|
||||
When spawning actors for specific sub-tasks from within an actor, it may be convenient to include the code to be executed directly in place, using an anonymous class.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#anonymous-actor
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#anonymous-actor
|
||||
|
||||
.. warning::
|
||||
|
||||
|
|
@ -170,7 +170,7 @@ In addition, it offers:
|
|||
|
||||
You can import the members in the :obj:`context` to avoid prefixing access with ``context.``
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#import-context
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#import-context
|
||||
|
||||
The remaining visible methods are user-overridable life-cycle hooks which are
|
||||
described in the following::
|
||||
|
|
@ -199,7 +199,7 @@ termination (see `Stopping Actors`_). This service is provided by the
|
|||
|
||||
Registering a monitor is easy:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#watch
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#watch
|
||||
|
||||
It should be noted that the :class:`Terminated` message is generated
|
||||
independent of the order in which registration and termination occur.
|
||||
|
|
@ -371,7 +371,7 @@ Ask: Send-And-Receive-Future
|
|||
The ``ask`` pattern involves actors as well as futures, hence it is offered as
|
||||
a use pattern rather than a method on :class:`ActorRef`:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#ask-pipeTo
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#ask-pipeTo
|
||||
|
||||
This example demonstrates ``ask`` together with the ``pipeTo`` pattern on
|
||||
futures, because this is likely to be a common combination. Please note that
|
||||
|
|
@ -391,7 +391,7 @@ To complete the future with an exception you need send a Failure message to the
|
|||
This is *not done automatically* when an actor throws an exception while processing a
|
||||
message.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#reply-exception
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#reply-exception
|
||||
|
||||
If the actor does not complete the future, it will expire after the timeout
|
||||
period, completing it with an :class:`AskTimeoutException`. The timeout is
|
||||
|
|
@ -399,11 +399,11 @@ taken from one of the following locations in order of precedence:
|
|||
|
||||
1. explicitly given timeout as in:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#using-explicit-timeout
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#using-explicit-timeout
|
||||
|
||||
2. implicit argument of type :class:`akka.util.Timeout`, e.g.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#using-implicit-timeout
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#using-implicit-timeout
|
||||
|
||||
See :ref:`futures-scala` for more information on how to await or query a
|
||||
future.
|
||||
|
|
@ -453,7 +453,7 @@ This method should return a ``PartialFunction``, e.g. a ‘match/case’ clause
|
|||
which the message can be matched against the different case clauses using Scala
|
||||
pattern matching. Here is an example:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala
|
||||
:include: imports1,my-actor
|
||||
|
||||
|
||||
|
|
@ -483,7 +483,7 @@ received within a certain time. To receive this timeout you have to set the
|
|||
``receiveTimeout`` property and declare a case handing the ReceiveTimeout
|
||||
object.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#receive-timeout
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#receive-timeout
|
||||
|
||||
.. _stopping-actors-scala:
|
||||
|
||||
|
|
@ -548,7 +548,7 @@ Graceful Stop
|
|||
:meth:`gracefulStop` is useful if you need to wait for termination or compose ordered
|
||||
termination of several actors:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#gracefulStop
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#gracefulStop
|
||||
|
||||
When ``gracefulStop()`` returns successfully, the actor’s ``postStop()`` hook
|
||||
will have been executed: there exists a happens-before edge between the end of
|
||||
|
|
@ -584,7 +584,7 @@ pushed and popped.
|
|||
|
||||
To hotswap the Actor behavior using ``become``:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#hot-swap-actor
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#hot-swap-actor
|
||||
|
||||
The ``become`` method is useful for many different things, but a particular nice
|
||||
example of it is in example where it is used to implement a Finite State Machine
|
||||
|
|
@ -594,12 +594,12 @@ example of it is in example where it is used to implement a Finite State Machine
|
|||
|
||||
Here is another little cute example of ``become`` and ``unbecome`` in action:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#swapper
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#swapper
|
||||
|
||||
Encoding Scala Actors nested receives without accidentally leaking memory
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
See this `Unnested receive example <https://github.com/akka/akka/blob/master/akka-docs/scala/code/akka/docs/actor/UnnestedReceives.scala>`_.
|
||||
See this `Unnested receive example <https://github.com/akka/akka/blob/master/akka-docs/scala/code/docs/actor/UnnestedReceives.scala>`_.
|
||||
|
||||
|
||||
Downgrade
|
||||
|
|
@ -675,8 +675,8 @@ A bit advanced but very useful way of defining a base message handler and then
|
|||
extend that, either through inheritance or delegation, is to use
|
||||
``PartialFunction.orElse`` chaining.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#receive-orElse
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#receive-orElse
|
||||
|
||||
Or:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#receive-orElse2
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#receive-orElse2
|
||||
|
|
|
|||
|
|
@ -36,22 +36,22 @@ Creating and stopping Agents
|
|||
Agents are created by invoking ``Agent(value)`` passing in the Agent's initial
|
||||
value:
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocSpec.scala#create
|
||||
.. includecode:: code/docs/agent/AgentDocSpec.scala#create
|
||||
|
||||
Note that creating an Agent requires an implicit ``ActorSystem`` (for creating
|
||||
the underlying actors). See :ref:`actor-systems` for more information about
|
||||
actor systems. An ActorSystem can be in implicit scope when creating an Agent:
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocSpec.scala#create-implicit-system
|
||||
.. includecode:: code/docs/agent/AgentDocSpec.scala#create-implicit-system
|
||||
|
||||
Or the ActorSystem can be passed explicitly when creating an Agent:
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocSpec.scala#create-explicit-system
|
||||
.. includecode:: code/docs/agent/AgentDocSpec.scala#create-explicit-system
|
||||
|
||||
An Agent will be running until you invoke ``close`` on it. Then it will be
|
||||
eligible for garbage collection (unless you hold on to it in some way).
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocSpec.scala#close
|
||||
.. includecode:: code/docs/agent/AgentDocSpec.scala#close
|
||||
|
||||
|
||||
Updating Agents
|
||||
|
|
@ -65,7 +65,7 @@ the update will be applied but dispatches to an Agent from a single thread will
|
|||
occur in order. You apply a value or a function by invoking the ``send``
|
||||
function.
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocSpec.scala#send
|
||||
.. includecode:: code/docs/agent/AgentDocSpec.scala#send
|
||||
|
||||
You can also dispatch a function to update the internal state but on its own
|
||||
thread. This does not use the reactive thread pool and can be used for
|
||||
|
|
@ -73,7 +73,7 @@ long-running or blocking operations. You do this with the ``sendOff``
|
|||
method. Dispatches using either ``sendOff`` or ``send`` will still be executed
|
||||
in order.
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocSpec.scala#send-off
|
||||
.. includecode:: code/docs/agent/AgentDocSpec.scala#send-off
|
||||
|
||||
|
||||
Reading an Agent's value
|
||||
|
|
@ -82,11 +82,11 @@ Reading an Agent's value
|
|||
Agents can be dereferenced (you can get an Agent's value) by invoking the Agent
|
||||
with parentheses like this:
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocSpec.scala#read-apply
|
||||
.. includecode:: code/docs/agent/AgentDocSpec.scala#read-apply
|
||||
|
||||
Or by using the get method:
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocSpec.scala#read-get
|
||||
.. includecode:: code/docs/agent/AgentDocSpec.scala#read-get
|
||||
|
||||
Reading an Agent's current value does not involve any message passing and
|
||||
happens immediately. So while updates to an Agent are asynchronous, reading the
|
||||
|
|
@ -99,12 +99,12 @@ Awaiting an Agent's value
|
|||
It is also possible to read the value after all currently queued sends have
|
||||
completed. You can do this with ``await``:
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocSpec.scala#read-await
|
||||
.. includecode:: code/docs/agent/AgentDocSpec.scala#read-await
|
||||
|
||||
You can also get a ``Future`` to this value, that will be completed after the
|
||||
currently queued updates have completed:
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocSpec.scala#read-future
|
||||
.. includecode:: code/docs/agent/AgentDocSpec.scala#read-future
|
||||
|
||||
|
||||
Transactional Agents
|
||||
|
|
@ -115,7 +115,7 @@ that transaction. If you send to an Agent within a transaction then the dispatch
|
|||
to the Agent will be held until that transaction commits, and discarded if the
|
||||
transaction is aborted. Here's an example:
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocSpec.scala#transfer-example
|
||||
.. includecode:: code/docs/agent/AgentDocSpec.scala#transfer-example
|
||||
|
||||
|
||||
Monadic usage
|
||||
|
|
@ -128,4 +128,4 @@ as-is. They are so-called 'persistent'.
|
|||
|
||||
Example of monadic usage:
|
||||
|
||||
.. includecode:: code/akka/docs/agent/AgentDocSpec.scala#monadic-example
|
||||
.. includecode:: code/docs/agent/AgentDocSpec.scala#monadic-example
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ Consumer
|
|||
Usage of Camel's integration components in Akka is essentially a
|
||||
one-liner. Here's an example.
|
||||
|
||||
.. includecode:: code/akka/docs/camel/Introduction.scala#Consumer-mina
|
||||
.. includecode:: code/docs/camel/Introduction.scala#Consumer-mina
|
||||
|
||||
The above example exposes an actor over a tcp endpoint on port 6200 via Apache
|
||||
Camel's `Mina component`_. The actor implements the endpointUri method to define
|
||||
|
|
@ -64,14 +64,14 @@ component`_), only the actor's endpointUri method must be changed.
|
|||
.. _Mina component: http://camel.apache.org/mina.html
|
||||
.. _Jetty component: http://camel.apache.org/jetty.html
|
||||
|
||||
.. includecode:: code/akka/docs/camel/Introduction.scala#Consumer
|
||||
.. includecode:: code/docs/camel/Introduction.scala#Consumer
|
||||
|
||||
Producer
|
||||
--------
|
||||
Actors can also trigger message exchanges with external systems i.e. produce to
|
||||
Camel endpoints.
|
||||
|
||||
.. includecode:: code/akka/docs/camel/Introduction.scala
|
||||
.. includecode:: code/docs/camel/Introduction.scala
|
||||
:include: imports,Producer
|
||||
|
||||
In the above example, any message sent to this actor will be sent to
|
||||
|
|
@ -127,7 +127,7 @@ messages from the ``file:data/input/actor`` Camel endpoint.
|
|||
|
||||
.. _Consumer: http://github.com/akka/akka/blob/master/akka-camel/src/main/scala/akka/camel/Consumer.scala
|
||||
|
||||
.. includecode:: code/akka/docs/camel/Consumers.scala#Consumer1
|
||||
.. includecode:: code/docs/camel/Consumers.scala#Consumer1
|
||||
|
||||
Whenever a file is put into the data/input/actor directory, its content is
|
||||
picked up by the Camel `file component`_ and sent as message to the
|
||||
|
|
@ -146,7 +146,7 @@ from localhost on port 8877.
|
|||
.. _Jetty component: http://camel.apache.org/jetty.html
|
||||
.. _Jetty: http://www.eclipse.org/jetty/
|
||||
|
||||
.. includecode:: code/akka/docs/camel/Consumers.scala#Consumer2
|
||||
.. includecode:: code/docs/camel/Consumers.scala#Consumer2
|
||||
|
||||
After starting the actor, clients can send messages to that actor by POSTing to
|
||||
``http://localhost:8877/camel/default``. The actor sends a response by using the
|
||||
|
|
|
|||
|
|
@ -1,24 +1,38 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
package docs.serialization
|
||||
|
||||
import org.scalatest.matchers.MustMatchers
|
||||
import akka.testkit._
|
||||
//#imports
|
||||
import akka.actor.{ ActorRef, ActorSystem }
|
||||
import akka.serialization._
|
||||
import com.typesafe.config.ConfigFactory
|
||||
//#extract-transport
|
||||
package object akka {
|
||||
// needs to be inside the akka package because accessing unsupported API !
|
||||
def transportOf(system: actor.ExtendedActorSystem): remote.RemoteTransport =
|
||||
system.provider match {
|
||||
case r: remote.RemoteActorRefProvider ⇒ r.transport
|
||||
case _ ⇒
|
||||
throw new UnsupportedOperationException(
|
||||
"this method requires the RemoteActorRefProvider to be configured")
|
||||
}
|
||||
}
|
||||
//#extract-transport
|
||||
|
||||
//#imports
|
||||
import akka.actor.ExtensionKey
|
||||
import akka.actor.ExtendedActorSystem
|
||||
import akka.actor.Extension
|
||||
import akka.actor.Address
|
||||
import akka.remote.RemoteActorRefProvider
|
||||
package docs.serialization {
|
||||
|
||||
//#my-own-serializer
|
||||
class MyOwnSerializer extends Serializer {
|
||||
import org.scalatest.matchers.MustMatchers
|
||||
import akka.testkit._
|
||||
//#imports
|
||||
import akka.actor.{ ActorRef, ActorSystem }
|
||||
import akka.serialization._
|
||||
import com.typesafe.config.ConfigFactory
|
||||
|
||||
//#imports
|
||||
import akka.actor.ExtensionKey
|
||||
import akka.actor.ExtendedActorSystem
|
||||
import akka.actor.Extension
|
||||
import akka.actor.Address
|
||||
import akka.remote.RemoteActorRefProvider
|
||||
|
||||
//#my-own-serializer
|
||||
class MyOwnSerializer extends Serializer {
|
||||
|
||||
// This is whether "fromBinary" requires a "clazz" or not
|
||||
def includeManifest: Boolean = false
|
||||
|
|
@ -46,13 +60,13 @@ class MyOwnSerializer extends Serializer {
|
|||
null
|
||||
//#...
|
||||
}
|
||||
}
|
||||
//#my-own-serializer
|
||||
}
|
||||
//#my-own-serializer
|
||||
|
||||
trait MyOwnSerializable
|
||||
case class Customer(name: String) extends MyOwnSerializable
|
||||
trait MyOwnSerializable
|
||||
case class Customer(name: String) extends MyOwnSerializable
|
||||
|
||||
class SerializationDocSpec extends AkkaSpec {
|
||||
class SerializationDocSpec extends AkkaSpec {
|
||||
"demonstrate configuration of serialize messages" in {
|
||||
//#serialize-messages-config
|
||||
val config = ConfigFactory.parseString("""
|
||||
|
|
@ -202,16 +216,12 @@ class SerializationDocSpec extends AkkaSpec {
|
|||
object ExternalAddress extends ExtensionKey[ExternalAddressExt]
|
||||
|
||||
class ExternalAddressExt(system: ExtendedActorSystem) extends Extension {
|
||||
def addressForAkka: Address = system.provider match {
|
||||
case r: RemoteActorRefProvider ⇒ r.transport.address
|
||||
case _ ⇒
|
||||
throw new UnsupportedOperationException(
|
||||
"this method requires the RemoteActorRefProvider to be configured")
|
||||
}
|
||||
def addressForAkka: Address = akka.transportOf(system).address
|
||||
}
|
||||
|
||||
def serializeAkkaDefault(ref: ActorRef): String =
|
||||
ref.path.toStringWithAddress(ExternalAddress(theActorSystem).addressForAkka)
|
||||
//#external-address-default
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
34
akka-docs/scala/code/docs/testkit/Specs2DemoAcceptance.scala
Normal file
34
akka-docs/scala/code/docs/testkit/Specs2DemoAcceptance.scala
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
package docs.testkit
|
||||
|
||||
import org.specs2._
|
||||
import org.specs2.specification.Scope
|
||||
|
||||
import akka.actor.{ Props, ActorSystem, Actor }
|
||||
import akka.testkit.{ TestKit, ImplicitSender }
|
||||
|
||||
class Specs2DemoAcceptance extends Specification {
|
||||
def is =
|
||||
|
||||
"This is a specification of basic TestKit interop" ^
|
||||
p ^
|
||||
"A TestKit should" ^
|
||||
"work properly with Specs2 acceptance tests" ! e1 ^
|
||||
"correctly convert durations" ! e2
|
||||
|
||||
val system = ActorSystem()
|
||||
|
||||
implicit def d2d(d: org.specs2.time.Duration): akka.util.FiniteDuration =
|
||||
akka.util.Duration(d.inMilliseconds, "millis")
|
||||
|
||||
def e1 = new TestKit(system) with Scope with ImplicitSender {
|
||||
within(1 second) {
|
||||
system.actorOf(Props(new Actor {
|
||||
def receive = { case x ⇒ sender ! x }
|
||||
})) ! "hallo"
|
||||
|
||||
expectMsgType[String] must be equalTo "hallo"
|
||||
}
|
||||
}
|
||||
|
||||
def e2 = ((1 second): akka.util.Duration).toMillis must be equalTo 1000
|
||||
}
|
||||
34
akka-docs/scala/code/docs/testkit/Specs2DemoSpec.scala
Normal file
34
akka-docs/scala/code/docs/testkit/Specs2DemoSpec.scala
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
package docs.testkit
|
||||
|
||||
import org.specs2.mutable.Specification
|
||||
import org.specs2.specification.Scope
|
||||
|
||||
import akka.actor.{ Props, ActorSystem, Actor }
|
||||
import akka.testkit.{ TestKit, ImplicitSender }
|
||||
|
||||
class Specs2DemoUnitSpec extends Specification {
|
||||
|
||||
val system = ActorSystem()
|
||||
|
||||
implicit def d2d(d: org.specs2.time.Duration): akka.util.FiniteDuration =
|
||||
akka.util.Duration(d.inMilliseconds, "millis")
|
||||
|
||||
/*
|
||||
* this is needed if different test cases would clash when run concurrently,
|
||||
* e.g. when creating specifically named top-level actors
|
||||
*/
|
||||
sequential
|
||||
|
||||
"A TestKit" should {
|
||||
"work properly with Specs2 unit tests" in
|
||||
new TestKit(system) with Scope with ImplicitSender {
|
||||
within(1 second) {
|
||||
system.actorOf(Props(new Actor {
|
||||
def receive = { case x ⇒ sender ! x }
|
||||
})) ! "hallo"
|
||||
|
||||
expectMsgType[String] must be equalTo "hallo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ Setting the dispatcher for an Actor
|
|||
|
||||
So in case you want to give your ``Actor`` a different dispatcher than the default, you need to do two things, of which the first is:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/dispatcher/DispatcherDocSpec.scala#defining-dispatcher
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#defining-dispatcher
|
||||
|
||||
.. note::
|
||||
The "dispatcherId" you specify in withDispatcher is in fact a path into your configuration.
|
||||
|
|
@ -27,11 +27,11 @@ So in case you want to give your ``Actor`` a different dispatcher than the defau
|
|||
|
||||
And then you just need to configure that dispatcher in your configuration:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/dispatcher/DispatcherDocSpec.scala#my-dispatcher-config
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#my-dispatcher-config
|
||||
|
||||
And here's another example that uses the "thread-pool-executor":
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/dispatcher/DispatcherDocSpec.scala#my-thread-pool-dispatcher-config
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#my-thread-pool-dispatcher-config
|
||||
|
||||
For more options, see the default-dispatcher section of the :ref:`configuration`.
|
||||
|
||||
|
|
@ -108,11 +108,11 @@ More dispatcher configuration examples
|
|||
|
||||
Configuring a ``PinnedDispatcher``:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/dispatcher/DispatcherDocSpec.scala#my-pinned-dispatcher-config
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#my-pinned-dispatcher-config
|
||||
|
||||
And then using it:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/dispatcher/DispatcherDocSpec.scala#defining-pinned-dispatcher
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#defining-pinned-dispatcher
|
||||
|
||||
Note that ``thread-pool-executor`` configuration as per the above ``my-thread-pool-dispatcher`` exmaple is
|
||||
NOT applicable. This is because every actor will have its own thread pool when using ``PinnedDispatcher``,
|
||||
|
|
@ -168,22 +168,22 @@ Mailbox configuration examples
|
|||
|
||||
How to create a PriorityMailbox:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/dispatcher/DispatcherDocSpec.scala#prio-mailbox
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#prio-mailbox
|
||||
|
||||
And then add it to the configuration:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/dispatcher/DispatcherDocSpec.scala#prio-dispatcher-config
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#prio-dispatcher-config
|
||||
|
||||
And then an example on how you would use it:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/dispatcher/DispatcherDocSpec.scala#prio-dispatcher
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#prio-dispatcher
|
||||
|
||||
Creating your own Mailbox type
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
An example is worth a thousand quacks:
|
||||
|
||||
.. includecode:: ../scala/code/akka/docs/dispatcher/DispatcherDocSpec.scala#mailbox-implementation-example
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#mailbox-implementation-example
|
||||
|
||||
And then you just specify the FQCN of your MailboxType as the value of the "mailbox-type" in the dispatcher configuration.
|
||||
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ Classification`_ which enables registering to related sets of channels (as is
|
|||
used for :class:`RemoteLifeCycleMessage`). The following example demonstrates
|
||||
how a simple subscription works:
|
||||
|
||||
.. includecode:: code/akka/docs/event/LoggingDocSpec.scala#deadletters
|
||||
.. includecode:: code/docs/event/LoggingDocSpec.scala#deadletters
|
||||
|
||||
Default Handlers
|
||||
----------------
|
||||
|
|
|
|||
|
|
@ -24,27 +24,27 @@ So let's create a sample extension that just lets us count the number of times s
|
|||
|
||||
First, we define what our ``Extension`` should do:
|
||||
|
||||
.. includecode:: code/akka/docs/extension/ExtensionDocSpec.scala
|
||||
.. includecode:: code/docs/extension/ExtensionDocSpec.scala
|
||||
:include: extension
|
||||
|
||||
Then we need to create an ``ExtensionId`` for our extension so we can grab ahold of it.
|
||||
|
||||
.. includecode:: code/akka/docs/extension/ExtensionDocSpec.scala
|
||||
.. includecode:: code/docs/extension/ExtensionDocSpec.scala
|
||||
:include: extensionid
|
||||
|
||||
Wicked! Now all we need to do is to actually use it:
|
||||
|
||||
.. includecode:: code/akka/docs/extension/ExtensionDocSpec.scala
|
||||
.. includecode:: code/docs/extension/ExtensionDocSpec.scala
|
||||
:include: extension-usage
|
||||
|
||||
Or from inside of an Akka Actor:
|
||||
|
||||
.. includecode:: code/akka/docs/extension/ExtensionDocSpec.scala
|
||||
.. includecode:: code/docs/extension/ExtensionDocSpec.scala
|
||||
:include: extension-usage-actor
|
||||
|
||||
You can also hide extension behind traits:
|
||||
|
||||
.. includecode:: code/akka/docs/extension/ExtensionDocSpec.scala
|
||||
.. includecode:: code/docs/extension/ExtensionDocSpec.scala
|
||||
:include: extension-usage-actor-trait
|
||||
|
||||
That's all there is to it!
|
||||
|
|
@ -55,7 +55,7 @@ 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/ExtensionDocSpec.scala
|
||||
.. includecode:: code/docs/extension/ExtensionDocSpec.scala
|
||||
:include: config
|
||||
|
||||
Note that in this case ``CountExtension`` is an object and therefore the class name ends with ``$``.
|
||||
|
|
@ -75,17 +75,17 @@ The :ref:`configuration` can be used for application specific settings. A good p
|
|||
|
||||
Sample configuration:
|
||||
|
||||
.. includecode:: code/akka/docs/extension/SettingsExtensionDocSpec.scala
|
||||
.. includecode:: code/docs/extension/SettingsExtensionDocSpec.scala
|
||||
:include: config
|
||||
|
||||
The ``Extension``:
|
||||
|
||||
.. includecode:: code/akka/docs/extension/SettingsExtensionDocSpec.scala
|
||||
.. includecode:: code/docs/extension/SettingsExtensionDocSpec.scala
|
||||
:include: imports,extension,extensionid
|
||||
|
||||
|
||||
Use it:
|
||||
|
||||
.. includecode:: code/akka/docs/extension/SettingsExtensionDocSpec.scala
|
||||
.. includecode:: code/docs/extension/SettingsExtensionDocSpec.scala
|
||||
:include: extension-usage-actor
|
||||
|
||||
|
|
|
|||
|
|
@ -51,5 +51,5 @@ Step Description
|
|||
Full Source Code of the Fault Tolerance Sample (Scala)
|
||||
------------------------------------------------------
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingDocSample.scala#all
|
||||
.. includecode:: code/docs/actor/FaultHandlingDocSample.scala#all
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ sample as it is easy to follow the log output to understand what is happening in
|
|||
|
||||
fault-tolerance-sample
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingDocSample.scala#all
|
||||
.. includecode:: code/docs/actor/FaultHandlingDocSample.scala#all
|
||||
:exclude: imports,messages,dummydb
|
||||
|
||||
Creating a Supervisor Strategy
|
||||
|
|
@ -35,7 +35,7 @@ in more depth.
|
|||
|
||||
For the sake of demonstration let us consider the following strategy:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FaultHandlingDocSpec.scala
|
||||
:include: strategy
|
||||
|
||||
I have chosen a few well-known exception types in order to demonstrate the
|
||||
|
|
@ -75,50 +75,50 @@ Test Application
|
|||
The following section shows the effects of the different directives in practice,
|
||||
wherefor a test setup is needed. First off, we need a suitable supervisor:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FaultHandlingDocSpec.scala
|
||||
:include: supervisor
|
||||
|
||||
This supervisor will be used to create a child, with which we can experiment:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FaultHandlingDocSpec.scala
|
||||
:include: child
|
||||
|
||||
The test is easier by using the utilities described in :ref:`akka-testkit`,
|
||||
where ``AkkaSpec`` is a convenient mixture of ``TestKit with WordSpec with
|
||||
MustMatchers``
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FaultHandlingDocSpec.scala
|
||||
:include: testkit
|
||||
|
||||
Let us create actors:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FaultHandlingDocSpec.scala
|
||||
:include: create
|
||||
|
||||
The first test shall demonstrate the ``Resume`` directive, so we try it out by
|
||||
setting some non-initial state in the actor and have it fail:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FaultHandlingDocSpec.scala
|
||||
:include: resume
|
||||
|
||||
As you can see the value 42 survives the fault handling directive. Now, if we
|
||||
change the failure to a more serious ``NullPointerException``, that will no
|
||||
longer be the case:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FaultHandlingDocSpec.scala
|
||||
:include: restart
|
||||
|
||||
And finally in case of the fatal ``IllegalArgumentException`` the child will be
|
||||
terminated by the supervisor:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FaultHandlingDocSpec.scala
|
||||
:include: stop
|
||||
|
||||
Up to now the supervisor was completely unaffected by the child’s failure,
|
||||
because the directives set did handle it. In case of an ``Exception``, this is not
|
||||
true anymore and the supervisor escalates the failure.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FaultHandlingDocSpec.scala
|
||||
:include: escalate-kill
|
||||
|
||||
The supervisor itself is supervised by the top-level actor provided by the
|
||||
|
|
@ -131,12 +131,12 @@ child not to survive this failure.
|
|||
In case this is not desired (which depends on the use case), we need to use a
|
||||
different supervisor which overrides this behavior.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FaultHandlingDocSpec.scala
|
||||
:include: supervisor2
|
||||
|
||||
With this parent, the child survives the escalated restart, as demonstrated in
|
||||
the last test:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FaultHandlingDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FaultHandlingDocSpec.scala
|
||||
:include: escalate-restart
|
||||
|
||||
|
|
|
|||
|
|
@ -30,17 +30,17 @@ send them on after the burst ended or a flush request is received.
|
|||
|
||||
First, consider all of the below to use these import statements:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala#simple-imports
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala#simple-imports
|
||||
|
||||
The contract of our “Buncher” actor is that is accepts or produces the following messages:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala#simple-events
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala#simple-events
|
||||
|
||||
``SetTarget`` is needed for starting it up, setting the destination for the
|
||||
``Batches`` to be passed on; ``Queue`` will add to the internal queue while
|
||||
``Flush`` will mark the end of a burst.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala#simple-state
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala#simple-state
|
||||
|
||||
The actor can be in two states: no message queued (aka ``Idle``) or some
|
||||
message queued (aka ``Active``). It will stay in the active state as long as
|
||||
|
|
@ -50,7 +50,7 @@ the actual queue of messages.
|
|||
|
||||
Now let’s take a look at the skeleton for our FSM actor:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala
|
||||
:include: simple-fsm
|
||||
:exclude: transition-elided,unhandled-elided
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ shall work identically in both states, we make use of the fact that any event
|
|||
which is not handled by the ``when()`` block is passed to the
|
||||
``whenUnhandled()`` block:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala#unhandled-elided
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala#unhandled-elided
|
||||
|
||||
The first case handled here is adding ``Queue()`` requests to the internal
|
||||
queue and going to the ``Active`` state (this does the obvious thing of staying
|
||||
|
|
@ -93,7 +93,7 @@ target, for which we use the ``onTransition`` mechanism: you can declare
|
|||
multiple such blocks and all of them will be tried for matching behavior in
|
||||
case a state transition occurs (i.e. only when the state actually changes).
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala#transition-elided
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala#transition-elided
|
||||
|
||||
The transition callback is a partial function which takes as input a pair of
|
||||
states—the current and the next state. The FSM trait includes a convenience
|
||||
|
|
@ -106,7 +106,7 @@ To verify that this buncher actually works, it is quite easy to write a test
|
|||
using the :ref:`akka-testkit`, which is conveniently bundled with ScalaTest traits
|
||||
into ``AkkaSpec``:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala
|
||||
:include: test-code
|
||||
:exclude: fsm-code-elided
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ The :class:`FSM` trait may only be mixed into an :class:`Actor`. Instead of
|
|||
extending :class:`Actor`, the self type approach was chosen in order to make it
|
||||
obvious that an actor is actually created:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala
|
||||
:include: simple-fsm
|
||||
:exclude: fsm-body
|
||||
|
||||
|
|
@ -165,7 +165,7 @@ The :meth:`stateFunction` argument is a :class:`PartialFunction[Event, State]`,
|
|||
which is conveniently given using the partial function literal syntax as
|
||||
demonstrated below:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala
|
||||
:include: when-syntax
|
||||
|
||||
The :class:`Event(msg: Any, data: D)` case class is parameterized with the data
|
||||
|
|
@ -189,7 +189,7 @@ If a state doesn't handle a received event a warning is logged. If you want to
|
|||
do something else in this case you can specify that with
|
||||
:func:`whenUnhandled(stateFunction)`:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala
|
||||
:include: unhandled-syntax
|
||||
|
||||
**IMPORTANT**: This handler is not stacked, meaning that each invocation of
|
||||
|
|
@ -230,7 +230,7 @@ of the modifiers described in the following:
|
|||
|
||||
All modifier can be chained to achieve a nice and concise description:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala
|
||||
:include: modifier-syntax
|
||||
|
||||
The parentheses are not actually needed in all cases, but they visually
|
||||
|
|
@ -267,7 +267,7 @@ The handler is a partial function which takes a pair of states as input; no
|
|||
resulting state is needed as it is not possible to modify the transition in
|
||||
progress.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala
|
||||
:include: transition-syntax
|
||||
|
||||
The convenience extractor :obj:`->` enables decomposition of the pair of states
|
||||
|
|
@ -280,7 +280,7 @@ It is also possible to pass a function object accepting two states to
|
|||
:func:`onTransition`, in case your transition handling logic is implemented as
|
||||
a method:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala
|
||||
:include: alt-transition-syntax
|
||||
|
||||
The handlers registered with this method are stacked, so you can intersperse
|
||||
|
|
@ -319,14 +319,14 @@ transformed using Scala’s full supplement of functional programming tools. In
|
|||
order to retain type inference, there is a helper function which may be used in
|
||||
case some common handling logic shall be applied to different clauses:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala
|
||||
:include: transform-syntax
|
||||
|
||||
It goes without saying that the arguments to this method may also be stored, to
|
||||
be used several times, e.g. when applying the same transformation to several
|
||||
``when()`` blocks:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala
|
||||
:include: alt-transform-syntax
|
||||
|
||||
Timers
|
||||
|
|
@ -371,14 +371,14 @@ state data which is available during termination handling.
|
|||
the same way as a state transition (but note that the ``return`` statement
|
||||
may not be used within a :meth:`when` block).
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala
|
||||
:include: stop-syntax
|
||||
|
||||
You can use :func:`onTermination(handler)` to specify custom code that is
|
||||
executed when the FSM is stopped. The handler is a partial function which takes
|
||||
a :class:`StopEvent(reason, stateName, stateData)` as argument:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala
|
||||
:include: termination-syntax
|
||||
|
||||
As for the :func:`whenUnhandled` case, this handler is not stacked, so each
|
||||
|
|
@ -412,7 +412,7 @@ Event Tracing
|
|||
The setting ``akka.actor.debug.fsm`` in :ref:`configuration` enables logging of an
|
||||
event trace by :class:`LoggingFSM` instances:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala
|
||||
:include: logging-fsm
|
||||
:exclude: body-elided
|
||||
|
||||
|
|
@ -433,7 +433,7 @@ The :class:`LoggingFSM` trait adds one more feature to the FSM: a rolling event
|
|||
log which may be used during debugging (for tracing how the FSM entered a
|
||||
certain failure state) or for other creative uses:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/FSMDocSpec.scala
|
||||
.. includecode:: code/docs/actor/FSMDocSpec.scala
|
||||
:include: logging-fsm
|
||||
|
||||
The :meth:`logDepth` defaults to zero, which turns off the event log.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ which is very similar to a ``java.util.concurrent.Executor``. if you have an ``A
|
|||
it will use its default dispatcher as the ``ExecutionContext``, or you can use the factory methods provided
|
||||
by the ``ExecutionContext`` companion object to wrap ``Executors`` and ``ExecutorServices``, or even create your own.
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: diy-execution-context
|
||||
|
||||
Use With Actors
|
||||
|
|
@ -30,7 +30,7 @@ which only works if the original sender was an ``Actor``) and the second is thro
|
|||
|
||||
Using an ``Actor``\'s ``?`` method to send a message will return a Future. To wait for and retrieve the actual result the simplest method is:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: ask-blocking
|
||||
|
||||
This will cause the current thread to block and wait for the ``Actor`` to 'complete' the ``Future`` with it's reply.
|
||||
|
|
@ -40,7 +40,7 @@ Alternatives to blocking are discussed further within this documentation. Also n
|
|||
an ``Actor`` is a ``Future[Any]`` since an ``Actor`` is dynamic. That is why the ``asInstanceOf`` is used in the above sample.
|
||||
When using non-blocking it is better to use the ``mapTo`` method to safely try to cast a ``Future`` to an expected type:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: map-to
|
||||
|
||||
The ``mapTo`` method will return a new ``Future`` that contains the result if the cast was successful,
|
||||
|
|
@ -53,7 +53,7 @@ A common use case within Akka is to have some computation performed concurrently
|
|||
If you find yourself creating a pool of ``Actor``\s for the sole reason of performing a calculation in parallel,
|
||||
there is an easier (and faster) way:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: future-eval
|
||||
|
||||
In the above code the block passed to ``Future`` will be executed by the default ``Dispatcher``,
|
||||
|
|
@ -63,12 +63,12 @@ and we also avoid the overhead of managing an ``Actor``.
|
|||
|
||||
You can also create already completed Futures using the ``Promise`` companion, which can be either successes:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: successful
|
||||
|
||||
Or failures:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: failed
|
||||
|
||||
Functional Futures
|
||||
|
|
@ -84,7 +84,7 @@ The first method for working with ``Future`` functionally is ``map``. This metho
|
|||
which performs some operation on the result of the ``Future``, and returning a new result.
|
||||
The return value of the ``map`` method is another ``Future`` that will contain the new result:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: map
|
||||
|
||||
In this example we are joining two strings together within a ``Future``. Instead of waiting for this to complete,
|
||||
|
|
@ -97,12 +97,12 @@ string "HelloWorld" and is unaffected by the ``map``.
|
|||
The ``map`` method is fine if we are modifying a single ``Future``,
|
||||
but if 2 or more ``Future``\s are involved ``map`` will not allow you to combine them together:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: wrong-nested-map
|
||||
|
||||
``f3`` is a ``Future[Future[Int]]`` instead of the desired ``Future[Int]``. Instead, the ``flatMap`` method should be used:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: flat-map
|
||||
|
||||
Composing futures using nested combinators it can sometimes become quite complicated and hard read, in these cases using Scala's
|
||||
|
|
@ -110,7 +110,7 @@ Composing futures using nested combinators it can sometimes become quite complic
|
|||
|
||||
If you need to do conditional propagation, you can use ``filter``:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: filter
|
||||
|
||||
For Comprehensions
|
||||
|
|
@ -118,7 +118,7 @@ For Comprehensions
|
|||
|
||||
Since ``Future`` has a ``map``, ``filter`` and ``flatMap`` method it can be easily used in a 'for comprehension':
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: for-comprehension
|
||||
|
||||
Something to keep in mind when doing this is even though it looks like parts of the above example can run in parallel,
|
||||
|
|
@ -134,14 +134,14 @@ A common use case for this is combining the replies of several ``Actor``\s into
|
|||
without resorting to calling ``Await.result`` or ``Await.ready`` to block for each result.
|
||||
First an example of using ``Await.result``:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: composing-wrong
|
||||
|
||||
Here we wait for the results from the first 2 ``Actor``\s before sending that result to the third ``Actor``.
|
||||
We called ``Await.result`` 3 times, which caused our little program to block 3 times before getting our final result.
|
||||
Now compare that to this example:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: composing
|
||||
|
||||
Here we have 2 actors processing a single message each. Once the 2 results are available
|
||||
|
|
@ -153,7 +153,7 @@ The ``sequence`` and ``traverse`` helper methods can make it easier to handle mo
|
|||
Both of these methods are ways of turning, for a subclass ``T`` of ``Traversable``, ``T[Future[A]]`` into a ``Future[T[A]]``.
|
||||
For example:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: sequence-ask
|
||||
|
||||
To better explain what happened in the example, ``Future.sequence`` is taking the ``List[Future[Int]]``
|
||||
|
|
@ -163,12 +163,12 @@ and we find the sum of the ``List``.
|
|||
The ``traverse`` method is similar to ``sequence``, but it takes a ``T[A]`` and a function ``A => Future[B]`` to return a ``Future[T[B]]``,
|
||||
where ``T`` is again a subclass of Traversable. For example, to use ``traverse`` to sum the first 100 odd numbers:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: traverse
|
||||
|
||||
This is the same result as this example:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: sequence
|
||||
|
||||
But it may be faster to use ``traverse`` as it doesn't have to create an intermediate ``List[Future[Int]]``.
|
||||
|
|
@ -178,7 +178,7 @@ from the type of the start-value and the type of the futures and returns somethi
|
|||
and then applies the function to all elements in the sequence of futures, asynchronously,
|
||||
the execution will start when the last of the Futures is completed.
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: fold
|
||||
|
||||
That's all it takes!
|
||||
|
|
@ -188,7 +188,7 @@ If the sequence passed to ``fold`` is empty, it will return the start-value, in
|
|||
In some cases you don't have a start-value and you're able to use the value of the first completing Future in the sequence
|
||||
as the start-value, you can use ``reduce``, it works like this:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: reduce
|
||||
|
||||
Same as with ``fold``, the execution will be done asynchronously when the last of the Future is completed,
|
||||
|
|
@ -200,13 +200,13 @@ Callbacks
|
|||
Sometimes you just want to listen to a ``Future`` being completed, and react to that not by creating a new Future, but by side-effecting.
|
||||
For this Akka supports ``onComplete``, ``onSuccess`` and ``onFailure``, of which the latter two are specializations of the first.
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: onSuccess
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: onFailure
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: onComplete
|
||||
|
||||
Define Ordering
|
||||
|
|
@ -218,7 +218,7 @@ But there's a solution and it's name is ``andThen``. It creates a new ``Future``
|
|||
the specified callback, a ``Future`` that will have the same result as the ``Future`` it's called on,
|
||||
which allows for ordering like in the following sample:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: and-then
|
||||
|
||||
Auxiliary Methods
|
||||
|
|
@ -227,13 +227,13 @@ Auxiliary Methods
|
|||
``Future`` ``fallbackTo`` combines 2 Futures into a new ``Future``, and will hold the successful value of the second ``Future``
|
||||
if the first ``Future`` fails.
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: fallback-to
|
||||
|
||||
You can also combine two Futures into a new ``Future`` that will hold a tuple of the two Futures successful results,
|
||||
using the ``zip`` operation.
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: zip
|
||||
|
||||
Exceptions
|
||||
|
|
@ -247,7 +247,7 @@ If a ``Future`` does contain an ``Exception``, calling ``Await.result`` will cau
|
|||
It is also possible to handle an ``Exception`` by returning a different result.
|
||||
This is done with the ``recover`` method. For example:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: recover
|
||||
|
||||
In this example, if the actor replied with a ``akka.actor.Status.Failure`` containing the ``ArithmeticException``,
|
||||
|
|
@ -258,6 +258,6 @@ it will behave as if we hadn't used the ``recover`` method.
|
|||
You can also use the ``recoverWith`` method, which has the same relationship to ``recover`` as ``flatMap`` has to ``map``,
|
||||
and is use like this:
|
||||
|
||||
.. includecode:: code/akka/docs/future/FutureDocSpec.scala
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: try-recover
|
||||
|
||||
|
|
|
|||
|
|
@ -103,29 +103,29 @@ Http Server
|
|||
|
||||
This example will create a simple high performance HTTP server. We begin with our imports:
|
||||
|
||||
.. includecode:: code/akka/docs/io/HTTPServer.scala
|
||||
.. includecode:: code/docs/io/HTTPServer.scala
|
||||
:include: imports
|
||||
|
||||
Some commonly used constants:
|
||||
|
||||
.. includecode:: code/akka/docs/io/HTTPServer.scala
|
||||
.. includecode:: code/docs/io/HTTPServer.scala
|
||||
:include: constants
|
||||
|
||||
And case classes to hold the resulting request:
|
||||
|
||||
.. includecode:: code/akka/docs/io/HTTPServer.scala
|
||||
.. includecode:: code/docs/io/HTTPServer.scala
|
||||
:include: request-class
|
||||
|
||||
Now for our first ``Iteratee``. There are 3 main sections of a HTTP request: the request line, the headers, and an optional body. The main request ``Iteratee`` handles each section separately:
|
||||
|
||||
.. includecode:: code/akka/docs/io/HTTPServer.scala
|
||||
.. includecode:: code/docs/io/HTTPServer.scala
|
||||
:include: read-request
|
||||
|
||||
In the above code ``readRequest`` takes the results of 3 different ``Iteratees`` (``readRequestLine``, ``readHeaders``, ``readBody``) and combines them into a single ``Request`` object. ``readRequestLine`` actually returns a tuple, so we extract it's individual components. ``readBody`` depends on values contained within the header section, so we must pass those to the method.
|
||||
|
||||
The request line has 3 parts to it: the HTTP method, the requested URI, and the HTTP version. The parts are separated by a single space, and the entire request line ends with a ``CRLF``.
|
||||
|
||||
.. includecode:: code/akka/docs/io/HTTPServer.scala
|
||||
.. includecode:: code/docs/io/HTTPServer.scala
|
||||
:include: read-request-line
|
||||
|
||||
Reading the request method is simple as it is a single string ending in a space. The simple ``Iteratee`` that performs this is ``IO.takeUntil(delimiter: ByteString): Iteratee[ByteString]``. It keeps consuming input until the specified delimiter is found. Reading the HTTP version is also a simple string that ends with a ``CRLF``.
|
||||
|
|
@ -134,14 +134,14 @@ The ``ascii`` method is a helper that takes a ``ByteString`` and parses it as a
|
|||
|
||||
Reading the request URI is a bit more complicated because we want to parse the individual components of the URI instead of just returning a simple string:
|
||||
|
||||
.. includecode:: code/akka/docs/io/HTTPServer.scala
|
||||
.. includecode:: code/docs/io/HTTPServer.scala
|
||||
:include: read-request-uri
|
||||
|
||||
For this example we are only interested in handling absolute paths. To detect if we the URI is an absolute path we use ``IO.peek(length: Int): Iteratee[ByteString]``, which returns a ``ByteString`` of the request length but doesn't actually consume the input. We peek at the next bit of input and see if it matches our ``PATH`` constant (defined above as ``ByteString("/")``). If it doesn't match we throw an error, but for a more robust solution we would want to handle other valid URIs.
|
||||
|
||||
Next we handle the path itself:
|
||||
|
||||
.. includecode:: code/akka/docs/io/HTTPServer.scala
|
||||
.. includecode:: code/docs/io/HTTPServer.scala
|
||||
:include: read-path
|
||||
|
||||
The ``step`` method is a recursive method that takes a ``List`` of the accumulated path segments. It first checks if the remaining input starts with the ``PATH`` constant, and if it does, it drops that input, and returns the ``readUriPart`` ``Iteratee`` which has it's result added to the path segment accumulator and the ``step`` method is run again.
|
||||
|
|
@ -150,39 +150,39 @@ If after reading in a path segment the next input does not start with a path, we
|
|||
|
||||
Following the path we read in the query (if it exists):
|
||||
|
||||
.. includecode:: code/akka/docs/io/HTTPServer.scala
|
||||
.. includecode:: code/docs/io/HTTPServer.scala
|
||||
:include: read-query
|
||||
|
||||
It is much simpler then reading the path since we aren't doing any parsing of the query since there is no standard format of the query string.
|
||||
|
||||
Both the path and query used the ``readUriPart`` ``Iteratee``, which is next:
|
||||
|
||||
.. includecode:: code/akka/docs/io/HTTPServer.scala
|
||||
.. includecode:: code/docs/io/HTTPServer.scala
|
||||
:include: read-uri-part
|
||||
|
||||
Here we have several ``Set``\s that contain valid characters pulled from the URI spec. The ``readUriPart`` method takes a ``Set`` of valid characters (already mapped to ``Byte``\s) and will continue to match characters until it reaches on that is not part of the ``Set``. If it is a percent encoded character then that is handled as a valid character and processing continues, or else we are done collecting this part of the URI.
|
||||
|
||||
Headers are next:
|
||||
|
||||
.. includecode:: code/akka/docs/io/HTTPServer.scala
|
||||
.. includecode:: code/docs/io/HTTPServer.scala
|
||||
:include: read-headers
|
||||
|
||||
And if applicable, we read in the message body:
|
||||
|
||||
.. includecode:: code/akka/docs/io/HTTPServer.scala
|
||||
.. includecode:: code/docs/io/HTTPServer.scala
|
||||
:include: read-body
|
||||
|
||||
Finally we get to the actual ``Actor``:
|
||||
|
||||
.. includecode:: code/akka/docs/io/HTTPServer.scala
|
||||
.. includecode:: code/docs/io/HTTPServer.scala
|
||||
:include: actor
|
||||
|
||||
And it's companion object:
|
||||
|
||||
.. includecode:: code/akka/docs/io/HTTPServer.scala
|
||||
.. includecode:: code/docs/io/HTTPServer.scala
|
||||
:include: actor-companion
|
||||
|
||||
A ``main`` method to start everything up:
|
||||
|
||||
.. includecode:: code/akka/docs/io/HTTPServer.scala
|
||||
.. includecode:: code/docs/io/HTTPServer.scala
|
||||
:include: main
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ How to Log
|
|||
Create a ``LoggingAdapter`` and use the ``error``, ``warning``, ``info``, or ``debug`` methods,
|
||||
as illustrated in this example:
|
||||
|
||||
.. includecode:: code/akka/docs/event/LoggingDocSpec.scala
|
||||
.. includecode:: code/docs/event/LoggingDocSpec.scala
|
||||
:include: my-actor
|
||||
|
||||
For convenience you can mixin the ``log`` member into actors, instead of defining it as above.
|
||||
|
|
@ -37,7 +37,7 @@ placeholders results in a warning being appended to the log statement (i.e. on
|
|||
the same line with the same severity). You may pass a Java array as the only
|
||||
substitution argument to have its elements be treated individually:
|
||||
|
||||
.. includecode:: code/akka/docs/event/LoggingDocSpec.scala#array
|
||||
.. includecode:: code/docs/event/LoggingDocSpec.scala#array
|
||||
|
||||
The Java :class:`Class` of the log source is also included in the generated
|
||||
:class:`LogEvent`. In case of a simple string this is replaced with a “marker”
|
||||
|
|
@ -176,7 +176,7 @@ using implicit parameters and thus fully customizable: simply create your own
|
|||
instance of :class:`LogSource[T]` and have it in scope when creating the
|
||||
logger.
|
||||
|
||||
.. includecode:: code/akka/docs/event/LoggingDocSpec.scala#my-source
|
||||
.. includecode:: code/docs/event/LoggingDocSpec.scala#my-source
|
||||
|
||||
This example creates a log source which mimics traditional usage of Java
|
||||
loggers, which are based upon the originating object’s class name as log
|
||||
|
|
@ -217,7 +217,7 @@ event handler available in the 'akka-slf4j' module.
|
|||
|
||||
Example of creating a listener:
|
||||
|
||||
.. includecode:: code/akka/docs/event/LoggingDocSpec.scala
|
||||
.. includecode:: code/docs/event/LoggingDocSpec.scala
|
||||
:include: my-event-listener
|
||||
|
||||
.. _slf4j-scala:
|
||||
|
|
|
|||
|
|
@ -116,15 +116,15 @@ precedence.
|
|||
|
||||
With these imports:
|
||||
|
||||
.. includecode:: code/akka/docs/remoting/RemoteDeploymentDocSpec.scala#import
|
||||
.. includecode:: code/docs/remoting/RemoteDeploymentDocSpec.scala#import
|
||||
|
||||
and a remote address like this:
|
||||
|
||||
.. includecode:: code/akka/docs/remoting/RemoteDeploymentDocSpec.scala#make-address
|
||||
.. includecode:: code/docs/remoting/RemoteDeploymentDocSpec.scala#make-address
|
||||
|
||||
you can advise the system to create a child on that remote node like so:
|
||||
|
||||
.. includecode:: code/akka/docs/remoting/RemoteDeploymentDocSpec.scala#deploy
|
||||
.. includecode:: code/docs/remoting/RemoteDeploymentDocSpec.scala#deploy
|
||||
|
||||
Serialization
|
||||
^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -21,17 +21,17 @@ Routers In Action
|
|||
|
||||
This is an example of how to create a router that is defined in configuration:
|
||||
|
||||
.. includecode:: code/akka/docs/routing/RouterViaConfigExample.scala#config
|
||||
.. includecode:: code/docs/routing/RouterViaConfigExample.scala#config
|
||||
|
||||
.. includecode:: code/akka/docs/routing/RouterViaConfigExample.scala#configurableRouting
|
||||
.. includecode:: code/docs/routing/RouterViaConfigExample.scala#configurableRouting
|
||||
|
||||
This is an example of how to programmatically create a router and set the number of routees it should create:
|
||||
|
||||
.. includecode:: code/akka/docs/routing/RouterViaProgramExample.scala#programmaticRoutingNrOfInstances
|
||||
.. includecode:: code/docs/routing/RouterViaProgramExample.scala#programmaticRoutingNrOfInstances
|
||||
|
||||
You can also give the router already created routees as in:
|
||||
|
||||
.. includecode:: code/akka/docs/routing/RouterViaProgramExample.scala#programmaticRoutingRoutees
|
||||
.. includecode:: code/docs/routing/RouterViaProgramExample.scala#programmaticRoutingRoutees
|
||||
|
||||
It should be noted that no actor factory or class needs to be provided in this
|
||||
case, as the ``Router`` will not create any children on its own (which is not
|
||||
|
|
@ -65,7 +65,7 @@ configuration in a :class:`RemoteRouterConfig`, attaching the remote addresses o
|
|||
the nodes to deploy to. Naturally, this requires your to include the
|
||||
``akka-remote`` module on your classpath:
|
||||
|
||||
.. includecode:: code/akka/docs/routing/RouterViaProgramExample.scala#remoteRoutees
|
||||
.. includecode:: code/docs/routing/RouterViaProgramExample.scala#remoteRoutees
|
||||
|
||||
How Routing is Designed within Akka
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -95,9 +95,9 @@ deterministic fashion. Since each actor knows its own external representation
|
|||
as well as that of its parent, the routees decide where replies should be sent
|
||||
when reacting to a message:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#reply-with-sender
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#reply-with-sender
|
||||
|
||||
.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#reply-without-sender
|
||||
.. includecode:: code/docs/actor/ActorDocSpec.scala#reply-without-sender
|
||||
|
||||
It is apparent now why routing needs to be enabled in code rather than being
|
||||
possible to “bolt on” later: whether or not an actor is routed means a change
|
||||
|
|
@ -141,11 +141,11 @@ Router usage
|
|||
In this section we will describe how to use the different router types.
|
||||
First we need to create some actors that will be used in the examples:
|
||||
|
||||
.. includecode:: code/akka/docs/routing/RouterTypeExample.scala#printlnActor
|
||||
.. includecode:: code/docs/routing/RouterTypeExample.scala#printlnActor
|
||||
|
||||
and
|
||||
|
||||
.. includecode:: code/akka/docs/routing/RouterTypeExample.scala#fibonacciActor
|
||||
.. includecode:: code/docs/routing/RouterTypeExample.scala#fibonacciActor
|
||||
|
||||
|
||||
RoundRobinRouter
|
||||
|
|
@ -153,7 +153,7 @@ RoundRobinRouter
|
|||
Routes in a `round-robin <http://en.wikipedia.org/wiki/Round-robin>`_ fashion to its routees.
|
||||
Code example:
|
||||
|
||||
.. includecode:: code/akka/docs/routing/RouterTypeExample.scala#roundRobinRouter
|
||||
.. includecode:: code/docs/routing/RouterTypeExample.scala#roundRobinRouter
|
||||
|
||||
When run you should see a similar output to this:
|
||||
|
||||
|
|
@ -182,7 +182,7 @@ the message it receives to this routee.
|
|||
This procedure will happen each time it receives a message.
|
||||
Code example:
|
||||
|
||||
.. includecode:: code/akka/docs/routing/RouterTypeExample.scala#randomRouter
|
||||
.. includecode:: code/docs/routing/RouterTypeExample.scala#randomRouter
|
||||
|
||||
When run you should see a similar output to this:
|
||||
|
||||
|
|
@ -215,14 +215,14 @@ The selection is done in this order:
|
|||
|
||||
Code example:
|
||||
|
||||
.. includecode:: code/akka/docs/routing/RouterTypeExample.scala#smallestMailboxRouter
|
||||
.. includecode:: code/docs/routing/RouterTypeExample.scala#smallestMailboxRouter
|
||||
|
||||
BroadcastRouter
|
||||
***************
|
||||
A broadcast router forwards the message it receives to *all* its routees.
|
||||
Code example:
|
||||
|
||||
.. includecode:: code/akka/docs/routing/RouterTypeExample.scala#broadcastRouter
|
||||
.. includecode:: code/docs/routing/RouterTypeExample.scala#broadcastRouter
|
||||
|
||||
When run you should see a similar output to this:
|
||||
|
||||
|
|
@ -242,7 +242,7 @@ The ScatterGatherFirstCompletedRouter will send the message on to all its routee
|
|||
It then waits for first result it gets back. This result will be sent back to original sender.
|
||||
Code example:
|
||||
|
||||
.. includecode:: code/akka/docs/routing/RouterTypeExample.scala#scatterGatherFirstCompletedRouter
|
||||
.. includecode:: code/docs/routing/RouterTypeExample.scala#scatterGatherFirstCompletedRouter
|
||||
|
||||
When run you should see this:
|
||||
|
||||
|
|
@ -274,16 +274,16 @@ of routees dynamically.
|
|||
|
||||
This is an example of how to create a resizable router that is defined in configuration:
|
||||
|
||||
.. includecode:: code/akka/docs/routing/RouterViaConfigExample.scala#config-resize
|
||||
.. includecode:: code/docs/routing/RouterViaConfigExample.scala#config-resize
|
||||
|
||||
.. includecode:: code/akka/docs/routing/RouterViaConfigExample.scala#configurableRoutingWithResizer
|
||||
.. includecode:: code/docs/routing/RouterViaConfigExample.scala#configurableRoutingWithResizer
|
||||
|
||||
Several more configuration options are available and described in ``akka.actor.deployment.default.resizer``
|
||||
section of the reference :ref:`configuration`.
|
||||
|
||||
This is an example of how to programmatically create a resizable router:
|
||||
|
||||
.. includecode:: code/akka/docs/routing/RouterViaProgramExample.scala#programmaticRoutingWithResizer
|
||||
.. includecode:: code/docs/routing/RouterViaProgramExample.scala#programmaticRoutingWithResizer
|
||||
|
||||
*It is also worth pointing out that if you define the ``router`` in the configuration file then this value
|
||||
will be used instead of any programmatically sent parameters.*
|
||||
|
|
@ -398,5 +398,5 @@ the actor system’s default dispatcher. All standard routers allow setting this
|
|||
property in their constructor or factory method, custom routers have to
|
||||
implement the method in a suitable way.
|
||||
|
||||
.. includecode:: code/akka/docs/routing/RouterDocSpec.scala#dispatchers
|
||||
.. includecode:: code/docs/routing/RouterDocSpec.scala#dispatchers
|
||||
|
||||
|
|
|
|||
|
|
@ -25,13 +25,13 @@ scheduled operation.
|
|||
Some examples
|
||||
-------------
|
||||
|
||||
.. includecode:: code/akka/docs/actor/SchedulerDocSpec.scala
|
||||
.. includecode:: code/docs/actor/SchedulerDocSpec.scala
|
||||
:include: imports1,schedule-one-off-message
|
||||
|
||||
.. includecode:: code/akka/docs/actor/SchedulerDocSpec.scala
|
||||
.. includecode:: code/docs/actor/SchedulerDocSpec.scala
|
||||
:include: schedule-one-off-thunk
|
||||
|
||||
.. includecode:: code/akka/docs/actor/SchedulerDocSpec.scala
|
||||
.. includecode:: code/docs/actor/SchedulerDocSpec.scala
|
||||
:include: schedule-recurring
|
||||
|
||||
From ``akka.actor.ActorSystem``
|
||||
|
|
|
|||
|
|
@ -21,12 +21,12 @@ For Akka to know which ``Serializer`` to use for what, you need edit your :ref:`
|
|||
in the "akka.actor.serializers"-section you bind names to implementations of the ``akka.serialization.Serializer``
|
||||
you wish to use, like this:
|
||||
|
||||
.. includecode:: code/akka/docs/serialization/SerializationDocSpec.scala#serialize-serializers-config
|
||||
.. includecode:: code/docs/serialization/SerializationDocSpec.scala#serialize-serializers-config
|
||||
|
||||
After you've bound names to different implementations of ``Serializer`` you need to wire which classes
|
||||
should be serialized using which ``Serializer``, this is done in the "akka.actor.serialization-bindings"-section:
|
||||
|
||||
.. includecode:: code/akka/docs/serialization/SerializationDocSpec.scala#serialization-bindings-config
|
||||
.. includecode:: code/docs/serialization/SerializationDocSpec.scala#serialization-bindings-config
|
||||
|
||||
You only need to specify the name of an interface or abstract base class of the
|
||||
messages. In case of ambiguity, i.e. the message implements several of the
|
||||
|
|
@ -53,7 +53,7 @@ Verification
|
|||
|
||||
If you want to verify that your messages are serializable you can enable the following config option:
|
||||
|
||||
.. includecode:: code/akka/docs/serialization/SerializationDocSpec.scala#serialize-messages-config
|
||||
.. includecode:: code/docs/serialization/SerializationDocSpec.scala#serialize-messages-config
|
||||
|
||||
.. warning::
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ If you want to verify that your messages are serializable you can enable the fol
|
|||
|
||||
If you want to verify that your ``Props`` are serializable you can enable the following config option:
|
||||
|
||||
.. includecode:: code/akka/docs/serialization/SerializationDocSpec.scala#serialize-creators-config
|
||||
.. includecode:: code/docs/serialization/SerializationDocSpec.scala#serialize-creators-config
|
||||
|
||||
.. warning::
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ Programmatic
|
|||
If you want to programmatically serialize/deserialize using Akka Serialization,
|
||||
here's some examples:
|
||||
|
||||
.. includecode:: code/akka/docs/serialization/SerializationDocSpec.scala
|
||||
.. includecode:: code/docs/serialization/SerializationDocSpec.scala
|
||||
:include: imports,programmatic
|
||||
|
||||
For more information, have a look at the ``ScalaDoc`` for ``akka.serialization._``
|
||||
|
|
@ -91,7 +91,7 @@ Creating new Serializers
|
|||
|
||||
First you need to create a class definition of your ``Serializer`` like so:
|
||||
|
||||
.. includecode:: code/akka/docs/serialization/SerializationDocSpec.scala
|
||||
.. includecode:: code/docs/serialization/SerializationDocSpec.scala
|
||||
:include: imports,my-own-serializer
|
||||
:exclude: ...
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ Serializing ActorRefs
|
|||
All ActorRefs are serializable using JavaSerializer, but in case you are writing your own serializer,
|
||||
you might want to know how to serialize and deserialize them properly, here's the magic incantation:
|
||||
|
||||
.. includecode:: code/akka/docs/serialization/SerializationDocSpec.scala
|
||||
.. includecode:: code/docs/serialization/SerializationDocSpec.scala
|
||||
:include: imports,actorref-serializer
|
||||
|
||||
.. note::
|
||||
|
|
@ -129,7 +129,7 @@ address which shall be the recipient of the serialized information. Use
|
|||
:meth:`ActorRefProvider.getExternalAddressFor(remoteAddr)` to query the system
|
||||
for the appropriate address to use when sending to ``remoteAddr``:
|
||||
|
||||
.. includecode:: code/akka/docs/serialization/SerializationDocSpec.scala
|
||||
.. includecode:: code/docs/serialization/SerializationDocSpec.scala
|
||||
:include: external-address
|
||||
|
||||
This requires that you know at least which type of address will be supported by
|
||||
|
|
@ -140,9 +140,17 @@ lenient as Akka’s RemoteActorRefProvider).
|
|||
|
||||
There is a possible simplification available if you are just using the default
|
||||
:class:`NettyRemoteTransport` with the :meth:`RemoteActorRefProvider`, which is
|
||||
enabled by the fact that this combination has just a single remote address:
|
||||
enabled by the fact that this combination has just a single remote address.
|
||||
This approach relies on internal API, which means that it is not guaranteed to
|
||||
be supported in future versions. To make this caveat more obvious, some bridge
|
||||
code in the ``akka`` package is required to make it work:
|
||||
|
||||
.. includecode:: code/akka/docs/serialization/SerializationDocSpec.scala
|
||||
.. includecode:: code/docs/serialization/SerializationDocSpec.scala
|
||||
:include: extract-transport
|
||||
|
||||
And with this, the address extraction goes like this:
|
||||
|
||||
.. includecode:: code/docs/serialization/SerializationDocSpec.scala
|
||||
:include: external-address-default
|
||||
|
||||
This solution has to be adapted once other providers are used (like the planned
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ Having access to the actual :class:`Actor` object allows application of all
|
|||
traditional unit testing techniques on the contained methods. Obtaining a
|
||||
reference is done like this:
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/TestkitDocSpec.scala#test-actor-ref
|
||||
.. includecode:: code/docs/testkit/TestkitDocSpec.scala#test-actor-ref
|
||||
|
||||
Since :class:`TestActorRef` is generic in the actor type it returns the
|
||||
underlying actor with its proper static type. From this point on you may bring
|
||||
|
|
@ -74,7 +74,7 @@ Testing that an expected exception is thrown while processing a message sent to
|
|||
the actor under test can be done by using a :class:`TestActorRef` :meth:`receive` based
|
||||
invocation:
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/TestkitDocSpec.scala#test-expecting-exceptions
|
||||
.. includecode:: code/docs/testkit/TestkitDocSpec.scala#test-expecting-exceptions
|
||||
|
||||
.. _TestFSMRef:
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ If your actor under test is a :class:`FSM`, you may use the special
|
|||
:class:`TestFSMRef` which offers all features of a normal :class:`TestActorRef`
|
||||
and in addition allows access to the internal state:
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/TestkitDocSpec.scala#test-fsm-ref
|
||||
.. includecode:: code/docs/testkit/TestkitDocSpec.scala#test-fsm-ref
|
||||
|
||||
Due to a limitation in Scala’s type inference, there is only the factory method
|
||||
shown above, so you will probably write code like ``TestFSMRef(new MyFSM)``
|
||||
|
|
@ -114,7 +114,7 @@ usual. This trick is made possible by the :class:`CallingThreadDispatcher`
|
|||
described below; this dispatcher is set implicitly for any actor instantiated
|
||||
into a :class:`TestActorRef`.
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/TestkitDocSpec.scala#test-behavior
|
||||
.. includecode:: code/docs/testkit/TestkitDocSpec.scala#test-behavior
|
||||
|
||||
As the :class:`TestActorRef` is a subclass of :class:`LocalActorRef` with a few
|
||||
special extras, also aspects like supervision and restarting work properly, but
|
||||
|
|
@ -143,7 +143,7 @@ any thrown exceptions, then there is another mode available for you: just use
|
|||
the :meth:`receive` method :class:`TestActorRef`, which will be forwarded to the
|
||||
underlying actor:
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/TestkitDocSpec.scala#test-unhandled
|
||||
.. includecode:: code/docs/testkit/TestkitDocSpec.scala#test-unhandled
|
||||
|
||||
The above sample assumes the default behavior for unhandled messages, i.e.
|
||||
that the actor doesn't swallow all messages and doesn't override :meth:`unhandled`.
|
||||
|
|
@ -182,7 +182,7 @@ single procedure drives the test.
|
|||
The :class:`TestKit` class contains a collection of tools which makes this
|
||||
common task easy.
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/PlainWordSpec.scala#plain-spec
|
||||
.. includecode:: code/docs/testkit/PlainWordSpec.scala#plain-spec
|
||||
|
||||
The :class:`TestKit` contains an actor named :obj:`testActor` which is the
|
||||
entry point for messages to be examined with the various ``expectMsg...``
|
||||
|
|
@ -339,7 +339,7 @@ handler with the :class:`TestEventListener` and using an :class:`EventFilter`
|
|||
allows assertions on log messages, including those which are generated by
|
||||
exceptions:
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/TestkitDocSpec.scala#event-filter
|
||||
.. includecode:: code/docs/testkit/TestkitDocSpec.scala#event-filter
|
||||
|
||||
.. _TestKit.within:
|
||||
|
||||
|
|
@ -372,7 +372,7 @@ It should be noted that if the last message-receiving assertion of the block is
|
|||
latencies. This means that while individual contained assertions still use the
|
||||
maximum time bound, the overall block may take arbitrarily longer in this case.
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/TestkitDocSpec.scala#test-within
|
||||
.. includecode:: code/docs/testkit/TestkitDocSpec.scala#test-within
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
@ -395,7 +395,7 @@ internally scaled by a factor taken from the :ref:`configuration`,
|
|||
You can scale other durations with the same factor by using the implicit conversion
|
||||
in ``akka.testkit`` package object to add dilated function to :class:`Duration`.
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/TestkitDocSpec.scala#duration-dilation
|
||||
.. includecode:: code/docs/testkit/TestkitDocSpec.scala#duration-dilation
|
||||
|
||||
Resolving Conflicts with Implicit ActorRef
|
||||
------------------------------------------
|
||||
|
|
@ -403,7 +403,7 @@ Resolving Conflicts with Implicit ActorRef
|
|||
If you want the sender of messages inside your TestKit-based tests to be the ``testActor``
|
||||
simply mix in ``ÌmplicitSender`` into your test.
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/PlainWordSpec.scala#implicit-sender
|
||||
.. includecode:: code/docs/testkit/PlainWordSpec.scala#implicit-sender
|
||||
|
||||
Using Multiple Probe Actors
|
||||
---------------------------
|
||||
|
|
@ -416,7 +416,7 @@ message flows. To make this more powerful and convenient, there is a concrete
|
|||
implementation called :class:`TestProbe`. The functionality is best explained
|
||||
using a small example:
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/TestkitDocSpec.scala
|
||||
.. includecode:: code/docs/testkit/TestkitDocSpec.scala
|
||||
:include: imports-test-probe,my-double-echo,test-probe
|
||||
|
||||
Here a the system under test is simulated by :class:`MyDoubleEcho`, which is
|
||||
|
|
@ -430,7 +430,7 @@ the test setup.
|
|||
Probes may also be equipped with custom assertions to make your test code even
|
||||
more concise and clear:
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/TestkitDocSpec.scala
|
||||
.. includecode:: code/docs/testkit/TestkitDocSpec.scala
|
||||
:include: test-special-probe
|
||||
|
||||
You have complete flexibility here in mixing and matching the :class:`TestKit`
|
||||
|
|
@ -444,7 +444,7 @@ Replying to Messages Received by Probes
|
|||
The probes keep track of the communications channel for replies, if possible,
|
||||
so they can also reply:
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/TestkitDocSpec.scala#test-probe-reply
|
||||
.. includecode:: code/docs/testkit/TestkitDocSpec.scala#test-probe-reply
|
||||
|
||||
Forwarding Messages Received by Probes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -455,7 +455,7 @@ sent to a :class:`TestProbe` ``probe`` instead, you can make assertions
|
|||
concerning volume and timing of the message flow while still keeping the
|
||||
network functioning:
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/TestkitDocSpec.scala
|
||||
.. includecode:: code/docs/testkit/TestkitDocSpec.scala
|
||||
:include: test-probe-forward-actors,test-probe-forward
|
||||
|
||||
The ``dest`` actor will receive the same message invocation as if no test probe
|
||||
|
|
@ -516,7 +516,7 @@ How to use it
|
|||
|
||||
Just set the dispatcher as you normally would:
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/TestkitDocSpec.scala#calling-thread-dispatcher
|
||||
.. includecode:: code/docs/testkit/TestkitDocSpec.scala#calling-thread-dispatcher
|
||||
|
||||
How it works
|
||||
------------
|
||||
|
|
@ -620,7 +620,7 @@ options:
|
|||
``akka.actor.debug.receive`` — which enables the :meth:`loggable`
|
||||
statement to be applied to an actor’s :meth:`receive` function:
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/TestkitDocSpec.scala#logging-receive
|
||||
.. includecode:: code/docs/testkit/TestkitDocSpec.scala#logging-receive
|
||||
|
||||
.
|
||||
If the abovementioned setting is not given in the :ref:`configuration`, this method will
|
||||
|
|
@ -659,3 +659,42 @@ full logging of actor activities using this configuration fragment::
|
|||
}
|
||||
}
|
||||
|
||||
Different Testing Frameworks
|
||||
============================
|
||||
|
||||
Akka’s own test suite is written using `ScalaTest <http://scalatest.org>`_,
|
||||
which also shines through in documentation examples. However, the TestKit and
|
||||
its facilities do not depend on that framework, you can essentially use
|
||||
whichever suits your development style best.
|
||||
|
||||
This section contains a collection of known gotchas with some other frameworks,
|
||||
which is by no means exhaustive and does not imply endorsement or special
|
||||
support.
|
||||
|
||||
Specs2
|
||||
------
|
||||
|
||||
Some `Specs2 <http://specs2.org>`_ users have contributed examples of how to work around some clashes which may arise:
|
||||
|
||||
* Mixing TestKit into :class:`org.specs2.mutable.Specification` results in a
|
||||
name clash involving the ``end`` method (which is a private variable in
|
||||
TestKit and an abstract method in Specification); if mixing in TestKit first,
|
||||
the code may compile but might then fail at runtime. The work-around—which is
|
||||
actually beneficial also for the third point—is to apply the TestKit together
|
||||
with :class:`org.specs2.specification.Scope`.
|
||||
* The Specification traits provide a :class:`Duration` DSL which uses partly
|
||||
the same method names as :class:`akka.util.Duration`, resulting in ambiguous
|
||||
implicits if ``akka.util.duration._`` is imported. The work-around is to use
|
||||
the Specification variants and supply an implicit conversion to the Akka
|
||||
Duration. This conversion is not supplied with the Akka distribution because
|
||||
that would mean that our JAR files would dependon Specs2, which is not
|
||||
justified by this little feature.
|
||||
* Specifications are by default executed concurrently, which requires some care
|
||||
when writing the tests or alternatively the ``sequential`` keyword.
|
||||
|
||||
You can use the following two examples as guidelines:
|
||||
|
||||
.. includecode:: code/docs/testkit/Specs2DemoSpec.scala
|
||||
|
||||
.. includecode:: code/docs/testkit/Specs2DemoAcceptance.scala
|
||||
|
||||
|
|
|
|||
|
|
@ -6,5 +6,5 @@ TestKit Example (Scala)
|
|||
|
||||
Ray Roestenburg's example code from `his blog <http://roestenburg.agilesquad.com/2011/02/unit-testing-akka-actors-with-testkit_12.html>`_ adapted to work with Akka 2.x.
|
||||
|
||||
.. includecode:: code/akka/docs/testkit/TestkitUsageSpec.scala#testkit-usage
|
||||
.. includecode:: code/docs/testkit/TestkitUsageSpec.scala#testkit-usage
|
||||
|
||||
|
|
|
|||
|
|
@ -63,9 +63,9 @@ Here is an example of coordinating two simple counter Actors so that they both
|
|||
increment together in coordinated transactions. If one of them was to fail to
|
||||
increment, the other would also fail.
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocSpec.scala#coordinated-example
|
||||
.. includecode:: code/docs/transactor/TransactorDocSpec.scala#coordinated-example
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocSpec.scala#run-coordinated-example
|
||||
.. includecode:: code/docs/transactor/TransactorDocSpec.scala#run-coordinated-example
|
||||
|
||||
Note that creating a ``Coordinated`` object requires a ``Timeout`` to be
|
||||
specified for the coordinated transaction. This can be done implicitly, by
|
||||
|
|
@ -73,36 +73,36 @@ having an implicit ``Timeout`` in scope, or explicitly, by passing the timeout
|
|||
when creating a a ``Coordinated`` object. Here's an example of specifying an
|
||||
implicit timeout:
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocSpec.scala#implicit-timeout
|
||||
.. includecode:: code/docs/transactor/TransactorDocSpec.scala#implicit-timeout
|
||||
|
||||
To start a new coordinated transaction that you will also participate in, just
|
||||
create a ``Coordinated`` object (this assumes an implicit timeout):
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocSpec.scala#create-coordinated
|
||||
.. includecode:: code/docs/transactor/TransactorDocSpec.scala#create-coordinated
|
||||
|
||||
To start a coordinated transaction that you won't participate in yourself you
|
||||
can create a ``Coordinated`` object with a message and send it directly to an
|
||||
actor. The recipient of the message will be the first member of the coordination
|
||||
set:
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocSpec.scala#send-coordinated
|
||||
.. includecode:: code/docs/transactor/TransactorDocSpec.scala#send-coordinated
|
||||
|
||||
To receive a coordinated message in an actor simply match it in a case
|
||||
statement:
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocSpec.scala#receive-coordinated
|
||||
.. includecode:: code/docs/transactor/TransactorDocSpec.scala#receive-coordinated
|
||||
:exclude: coordinated-atomic
|
||||
|
||||
To include another actor in the same coordinated transaction that you've created
|
||||
or received, use the apply method on that object. This will increment the number
|
||||
of parties involved by one and create a new ``Coordinated`` object to be sent.
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocSpec.scala#include-coordinated
|
||||
.. includecode:: code/docs/transactor/TransactorDocSpec.scala#include-coordinated
|
||||
|
||||
To enter the coordinated transaction use the atomic method of the coordinated
|
||||
object:
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocSpec.scala#coordinated-atomic
|
||||
.. includecode:: code/docs/transactor/TransactorDocSpec.scala#coordinated-atomic
|
||||
|
||||
The coordinated transaction will wait for the other transactions before
|
||||
committing. If any of the coordinated transactions fail then they all fail.
|
||||
|
|
@ -125,7 +125,7 @@ transactions, using the explicit coordination described above.
|
|||
Here's an example of a simple transactor that will join a coordinated
|
||||
transaction:
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocSpec.scala#counter-example
|
||||
.. includecode:: code/docs/transactor/TransactorDocSpec.scala#counter-example
|
||||
|
||||
You could send this Counter transactor a ``Coordinated(Increment)`` message. If
|
||||
you were to send it just an ``Increment`` message it will create its own
|
||||
|
|
@ -141,16 +141,16 @@ allows you to specify both the actor to send to, and the message to send.
|
|||
|
||||
Example of coordinating an increment:
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocSpec.scala#friendly-counter-example
|
||||
.. includecode:: code/docs/transactor/TransactorDocSpec.scala#friendly-counter-example
|
||||
|
||||
Using ``include`` to include more than one transactor:
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocSpec.scala#coordinate-include
|
||||
.. includecode:: code/docs/transactor/TransactorDocSpec.scala#coordinate-include
|
||||
|
||||
Using ``sendTo`` to coordinate transactions but pass-on a different message than
|
||||
the one that was received:
|
||||
|
||||
.. includecode:: code/akka/docs/transactor/TransactorDocSpec.scala#coordinate-sendto
|
||||
.. includecode:: code/docs/transactor/TransactorDocSpec.scala#coordinate-sendto
|
||||
|
||||
To execute directly before or after the coordinated transaction, override the
|
||||
``before`` and ``after`` methods. These methods also expect partial functions
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ The tools of the trade
|
|||
Before we create our first Typed Actor we should first go through the tools that we have at our disposal,
|
||||
it's located in ``akka.actor.TypedActor``.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocSpec.scala
|
||||
.. includecode:: code/docs/actor/TypedActorDocSpec.scala
|
||||
:include: typed-actor-extension-tools
|
||||
|
||||
.. warning::
|
||||
|
|
@ -55,37 +55,37 @@ To create a Typed Actor you need to have one or more interfaces, and one impleme
|
|||
|
||||
Our example interface:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocSpec.scala
|
||||
.. includecode:: code/docs/actor/TypedActorDocSpec.scala
|
||||
:include: imports,typed-actor-iface
|
||||
:exclude: typed-actor-iface-methods
|
||||
|
||||
Our example implementation of that interface:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocSpec.scala
|
||||
.. includecode:: code/docs/actor/TypedActorDocSpec.scala
|
||||
:include: imports,typed-actor-impl
|
||||
:exclude: typed-actor-impl-methods
|
||||
|
||||
The most trivial way of creating a Typed Actor instance
|
||||
of our Squarer:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocSpec.scala
|
||||
.. includecode:: code/docs/actor/TypedActorDocSpec.scala
|
||||
:include: typed-actor-create1
|
||||
|
||||
First type is the type of the proxy, the second type is the type of the implementation.
|
||||
If you need to call a specific constructor you do it like this:
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocSpec.scala
|
||||
.. includecode:: code/docs/actor/TypedActorDocSpec.scala
|
||||
:include: typed-actor-create2
|
||||
|
||||
Since you supply a Props, you can specify which dispatcher to use, what the default timeout should be used and more.
|
||||
Now, our Squarer doesn't have any methods, so we'd better add those.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocSpec.scala
|
||||
.. includecode:: code/docs/actor/TypedActorDocSpec.scala
|
||||
:include: imports,typed-actor-iface
|
||||
|
||||
Alright, now we've got some methods we can call, but we need to implement those in SquarerImpl.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocSpec.scala
|
||||
.. includecode:: code/docs/actor/TypedActorDocSpec.scala
|
||||
:include: imports,typed-actor-impl
|
||||
|
||||
Excellent, now we have an interface and an implementation of that interface,
|
||||
|
|
@ -113,7 +113,7 @@ we *strongly* recommend that parameters passed are immutable.
|
|||
One-way message send
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocSpec.scala
|
||||
.. includecode:: code/docs/actor/TypedActorDocSpec.scala
|
||||
:include: typed-actor-call-oneway
|
||||
|
||||
As simple as that! The method will be executed on another thread; asynchronously.
|
||||
|
|
@ -121,13 +121,13 @@ As simple as that! The method will be executed on another thread; asynchronously
|
|||
Request-reply message send
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocSpec.scala
|
||||
.. includecode:: code/docs/actor/TypedActorDocSpec.scala
|
||||
:include: typed-actor-call-option
|
||||
|
||||
This will block for as long as the timeout that was set in the Props of the Typed Actor,
|
||||
if needed. It will return ``None`` if a timeout occurs.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocSpec.scala
|
||||
.. includecode:: code/docs/actor/TypedActorDocSpec.scala
|
||||
:include: typed-actor-call-strict
|
||||
|
||||
This will block for as long as the timeout that was set in the Props of the Typed Actor,
|
||||
|
|
@ -136,7 +136,7 @@ if needed. It will throw a ``java.util.concurrent.TimeoutException`` if a timeou
|
|||
Request-reply-with-future message send
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocSpec.scala
|
||||
.. includecode:: code/docs/actor/TypedActorDocSpec.scala
|
||||
:include: typed-actor-call-future
|
||||
|
||||
This call is asynchronous, and the Future returned can be used for asynchronous composition.
|
||||
|
|
@ -146,12 +146,12 @@ Stopping Typed Actors
|
|||
|
||||
Since Akkas Typed Actors are backed by Akka Actors they must be stopped when they aren't needed anymore.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocSpec.scala
|
||||
.. includecode:: code/docs/actor/TypedActorDocSpec.scala
|
||||
:include: typed-actor-stop
|
||||
|
||||
This asynchronously stops the Typed Actor associated with the specified proxy ASAP.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocSpec.scala
|
||||
.. includecode:: code/docs/actor/TypedActorDocSpec.scala
|
||||
:include: typed-actor-poisonpill
|
||||
|
||||
This asynchronously stops the Typed Actor associated with the specified proxy
|
||||
|
|
@ -208,13 +208,13 @@ Lookup & Remoting
|
|||
|
||||
Since ``TypedActors`` are backed by ``Akka Actors``, you can use ``actorFor`` together with ``typedActorOf`` to proxy ``ActorRefs`` potentially residing on remote nodes.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocSpec.scala#typed-actor-remote
|
||||
.. includecode:: code/docs/actor/TypedActorDocSpec.scala#typed-actor-remote
|
||||
|
||||
Supercharging
|
||||
-------------
|
||||
|
||||
Here's an example on how you can use traits to mix in behavior in your Typed Actors.
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocSpec.scala#typed-actor-supercharge
|
||||
.. includecode:: code/docs/actor/TypedActorDocSpec.scala#typed-actor-supercharge
|
||||
|
||||
.. includecode:: code/akka/docs/actor/TypedActorDocSpec.scala#typed-actor-supercharge-usage
|
||||
.. includecode:: code/docs/actor/TypedActorDocSpec.scala#typed-actor-supercharge-usage
|
||||
|
|
|
|||
|
|
@ -19,18 +19,18 @@ Connection
|
|||
ZeroMQ supports multiple connectivity patterns, each aimed to meet a different set of requirements. Currently, this module supports publisher-subscriber connections and connections based on dealers and routers. For connecting or accepting connections, a socket must be created.
|
||||
Sockets are always created using the ``akka.zeromq.ZeroMQExtension``, for example:
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocSpec.scala#pub-socket
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocSpec.scala#pub-socket
|
||||
|
||||
or by importing the ``akka.zeromq._`` package to make newSocket method available on system, via an implicit conversion.
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocSpec.scala#pub-socket2
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocSpec.scala#pub-socket2
|
||||
|
||||
|
||||
Above examples will create a ZeroMQ Publisher socket that is Bound to the port 1234 on localhost.
|
||||
|
||||
Similarly you can create a subscription socket, with a listener, that subscribes to all messages from the publisher using:
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocSpec.scala#sub-socket
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocSpec.scala#sub-socket
|
||||
|
||||
The following sub-sections describe the supported connection patterns and how they can be used in an Akka environment. However, for a comprehensive discussion of connection patterns, please refer to `ZeroMQ -- The Guide <http://zguide.zeromq.org/page:all>`_.
|
||||
|
||||
|
|
@ -46,18 +46,18 @@ When you're using zeromq pub/sub you should be aware that it needs multicast - c
|
|||
|
||||
An actor is subscribed to a topic as follows:
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocSpec.scala#sub-topic-socket
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocSpec.scala#sub-topic-socket
|
||||
|
||||
It is a prefix match so it is subscribed to all topics starting with ``foo.bar``. Note that if the given string is empty or
|
||||
``SubscribeAll`` is used, the actor is subscribed to all topics.
|
||||
|
||||
To unsubscribe from a topic you do the following:
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocSpec.scala#unsub-topic-socket
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocSpec.scala#unsub-topic-socket
|
||||
|
||||
To publish messages to a topic you must use two Frames with the topic in the first frame.
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocSpec.scala#pub-topic
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocSpec.scala#pub-topic
|
||||
|
||||
Pub-Sub in Action
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -67,16 +67,16 @@ The following example illustrates one publisher with two subscribers.
|
|||
The publisher monitors current heap usage and system load and periodically publishes ``Heap`` events on the ``"health.heap"`` topic
|
||||
and ``Load`` events on the ``"health.load"`` topic.
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocSpec.scala#health
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocSpec.scala#health
|
||||
|
||||
Let's add one subscriber that logs the information. It subscribes to all topics starting with ``"health"``, i.e. both ``Heap`` and
|
||||
``Load`` events.
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocSpec.scala#logger
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocSpec.scala#logger
|
||||
|
||||
Another subscriber keep track of used heap and warns if too much heap is used. It only subscribes to ``Heap`` events.
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocSpec.scala#alerter
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocSpec.scala#alerter
|
||||
|
||||
Router-Dealer Connection
|
||||
------------------------
|
||||
|
|
@ -87,7 +87,7 @@ With those socket types you can build your own reliable pub sub broker that uses
|
|||
|
||||
To create a Router socket that has a high watermark configured, you would do:
|
||||
|
||||
.. includecode:: code/akka/docs/zeromq/ZeromqDocSpec.scala#high-watermark
|
||||
.. includecode:: code/docs/zeromq/ZeromqDocSpec.scala#high-watermark
|
||||
|
||||
The akka-zeromq module accepts most if not all the available configuration options for a zeromq socket.
|
||||
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ object Dependencies {
|
|||
|
||||
val tutorials = Seq(Test.scalatest, Test.junit)
|
||||
|
||||
val docs = Seq(Test.scalatest, Test.junit)
|
||||
val docs = Seq(Test.scalatest, Test.junit, Test.specs2)
|
||||
|
||||
val zeroMQ = Seq(protobuf, Dependency.zeroMQ, Test.scalatest, Test.junit)
|
||||
}
|
||||
|
|
@ -452,6 +452,7 @@ object Dependency {
|
|||
val mockito = "org.mockito" % "mockito-all" % "1.8.1" % "test" // MIT
|
||||
val scalatest = "org.scalatest" % "scalatest_2.9.1" % V.Scalatest % "test" // ApacheV2
|
||||
val scalacheck = "org.scala-tools.testing" % "scalacheck_2.9.1" % "1.9" % "test" // New BSD
|
||||
val specs2 = "org.specs2" % "specs2_2.9.1" % "1.9" % "test" // Modified BSD / ApacheV2
|
||||
val zookeeper = "org.apache.hadoop.zookeeper" % "zookeeper" % "3.4.0" % "test" // ApacheV2
|
||||
val log4j = "log4j" % "log4j" % "1.2.14" % "test" // ApacheV2
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue