Split mailbox documentation into a separate section. See #3341
This commit is contained in:
parent
beed693c1b
commit
6abec367f2
10 changed files with 330 additions and 326 deletions
|
|
@ -141,159 +141,3 @@ Note that it's not guaranteed that the *same* thread is used over time, since th
|
|||
is used for ``PinnedDispatcher`` to keep resource usage down in case of idle actors. To use the same
|
||||
thread all the time you need to add ``thread-pool-executor.allow-core-timeout=off`` to the
|
||||
configuration of the ``PinnedDispatcher``.
|
||||
|
||||
Mailboxes
|
||||
---------
|
||||
|
||||
An Akka ``Mailbox`` holds the messages that are destined for an ``Actor``.
|
||||
Normally each ``Actor`` has its own mailbox, but with example a ``BalancingDispatcher`` all actors with the same ``BalancingDispatcher`` will share a single instance.
|
||||
|
||||
Builtin implementations
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Akka comes shipped with a number of default mailbox implementations:
|
||||
|
||||
* UnboundedMailbox
|
||||
|
||||
- Backed by a ``java.util.concurrent.ConcurrentLinkedQueue``
|
||||
|
||||
- Blocking: No
|
||||
|
||||
- Bounded: No
|
||||
|
||||
* BoundedMailbox
|
||||
|
||||
- Backed by a ``java.util.concurrent.LinkedBlockingQueue``
|
||||
|
||||
- Blocking: Yes
|
||||
|
||||
- Bounded: Yes
|
||||
|
||||
* UnboundedPriorityMailbox
|
||||
|
||||
- Backed by a ``java.util.concurrent.PriorityBlockingQueue``
|
||||
|
||||
- Blocking: Yes
|
||||
|
||||
- Bounded: No
|
||||
|
||||
* BoundedPriorityMailbox
|
||||
|
||||
- Backed by a ``java.util.PriorityBlockingQueue`` wrapped in an ``akka.util.BoundedBlockingQueue``
|
||||
|
||||
- Blocking: Yes
|
||||
|
||||
- Bounded: Yes
|
||||
|
||||
* Durable mailboxes, see :ref:`durable-mailboxes-java`.
|
||||
|
||||
Mailbox configuration examples
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
How to create a PriorityMailbox:
|
||||
|
||||
.. includecode:: ../java/code/docs/dispatcher/DispatcherDocTest.java#prio-mailbox
|
||||
|
||||
And then add it to the configuration:
|
||||
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#prio-dispatcher-config
|
||||
|
||||
And then an example on how you would use it:
|
||||
|
||||
.. includecode:: ../java/code/docs/dispatcher/DispatcherDocTest.java#prio-dispatcher
|
||||
|
||||
It is also possible to configure a mailbox type directly like this:
|
||||
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala
|
||||
:include: prio-mailbox-config-java,mailbox-deployment-config
|
||||
|
||||
And then use it either from deployment like this:
|
||||
|
||||
.. includecode:: code/docs/dispatcher/DispatcherDocTest.java#defining-mailbox-in-config
|
||||
|
||||
Or code like this:
|
||||
|
||||
.. includecode:: code/docs/dispatcher/DispatcherDocTest.java#defining-mailbox-in-code
|
||||
|
||||
|
||||
Requiring a message queue type for an Actor
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
It is possible to require a certain type of message queue for a certain type of actor
|
||||
by having that actor implement the parameterized interface :class:`RequiresMessageQueue`. Here is
|
||||
an example:
|
||||
|
||||
.. includecode:: code/docs/actor/MyBoundedUntypedActor.java#my-bounded-untyped-actor
|
||||
|
||||
The type parameter to the :class:`RequiresMessageQueue` interface needs to be mapped to a mailbox in
|
||||
configuration like this:
|
||||
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala
|
||||
:include: bounded-mailbox-config,required-mailbox-config
|
||||
|
||||
Now every time you create an actor of type :class:`MyBoundedUntypedActor` it will try to get a bounded
|
||||
mailbox. If the actor has a different mailbox configured in deployment, either directly or via
|
||||
a dispatcher with a specified mailbox type, then that will override this mapping.
|
||||
|
||||
.. note::
|
||||
|
||||
The type of the queue in the mailbox created for an actor will be checked against the required type in the
|
||||
interface and if the queue doesn't implement the required type then actor creation will fail.
|
||||
|
||||
|
||||
Mailbox configuration precedence
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The order of precedence for the mailbox type of an actor, where lower numbers override higher, is:
|
||||
|
||||
1. Mailbox type configured in the deployment of the actor
|
||||
2. Mailbox type configured on the dispatcher of the actor
|
||||
3. Mailbox type configured on the Props of the actor
|
||||
4. Mailbox type configured via message queue requirement
|
||||
|
||||
|
||||
Creating your own Mailbox type
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
An example is worth a thousand quacks:
|
||||
|
||||
.. includecode:: code/docs/dispatcher/DispatcherDocTest.java#imports-custom
|
||||
|
||||
.. includecode:: code/docs/dispatcher/DispatcherDocTest.java#mailbox-implementation-example
|
||||
|
||||
And then you just specify the FQCN of your MailboxType as the value of the "mailbox-type" in the dispatcher
|
||||
configuration, or the mailbox configuration.
|
||||
|
||||
.. note::
|
||||
|
||||
Make sure to include a constructor which takes
|
||||
``akka.actor.ActorSystem.Settings`` and ``com.typesafe.config.Config``
|
||||
arguments, as this constructor is invoked reflectively to construct your
|
||||
mailbox type. The config passed in as second argument is that section from
|
||||
the configuration which describes the dispatcher or mailbox setting using
|
||||
this mailbox type; the mailbox type will be instantiated once for each
|
||||
dispatcher or mailbox setting using it.
|
||||
|
||||
|
||||
Special Semantics of ``system.actorOf``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In order to make ``system.actorOf`` both synchronous and non-blocking while
|
||||
keeping the return type :class:`ActorRef` (and the semantics that the returned
|
||||
ref is fully functional), special handling takes place for this case. Behind
|
||||
the scenes, a hollow kind of actor reference is constructed, which is sent to
|
||||
the system’s guardian actor who actually creates the actor and its context and
|
||||
puts those inside the reference. Until that has happened, messages sent to the
|
||||
:class:`ActorRef` will be queued locally, and only upon swapping the real
|
||||
filling in will they be transferred into the real mailbox. Thus,
|
||||
|
||||
.. code-block:: scala
|
||||
|
||||
final Props props = ...
|
||||
// this actor uses MyCustomMailbox, which is assumed to be a singleton
|
||||
system.actorOf(props.withDispatcher("myCustomMailbox").tell("bang", sender);
|
||||
assert(MyCustomMailbox.getInstance().getLastEnqueued().equals("bang"));
|
||||
|
||||
will probably fail; you will have to allow for some time to pass and retry the
|
||||
check à la :meth:`TestKit.awaitCond`.
|
||||
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ mailbox when the node of the actor resides on crashes, then when you restart the
|
|||
node, the actor will be able to continue processing as if nothing had happened;
|
||||
with all pending messages still in its mailbox.
|
||||
|
||||
You configure durable mailboxes through the dispatcher. The actor is oblivious
|
||||
to which type of mailbox it is using.
|
||||
You configure durable mailboxes through the dispatcher or the actor deployment (see
|
||||
:ref:`mailboxes-java`). The actor is oblivious to which type of mailbox it is using.
|
||||
|
||||
This gives you an excellent way of creating bulkheads in your application, where
|
||||
groups of actors sharing the same dispatcher also share the same backing
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ Actors
|
|||
typed-actors
|
||||
fault-tolerance
|
||||
dispatchers
|
||||
mailboxes
|
||||
routing
|
||||
fsm
|
||||
testing
|
||||
|
|
|
|||
158
akka-docs/rst/java/mailboxes.rst
Normal file
158
akka-docs/rst/java/mailboxes.rst
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
.. _mailboxes-java:
|
||||
|
||||
Mailboxes
|
||||
=========
|
||||
|
||||
An Akka ``Mailbox`` holds the messages that are destined for an ``Actor``.
|
||||
Normally each ``Actor`` has its own mailbox, but with for example a ``BalancingDispatcher``
|
||||
all actors with the same ``BalancingDispatcher`` will share a single instance.
|
||||
|
||||
Builtin Mailbox Implementations
|
||||
-------------------------------
|
||||
|
||||
Akka comes shipped with a number of default mailbox implementations:
|
||||
|
||||
* UnboundedMailbox
|
||||
|
||||
- Backed by a ``java.util.concurrent.ConcurrentLinkedQueue``
|
||||
|
||||
- Blocking: No
|
||||
|
||||
- Bounded: No
|
||||
|
||||
* BoundedMailbox
|
||||
|
||||
- Backed by a ``java.util.concurrent.LinkedBlockingQueue``
|
||||
|
||||
- Blocking: Yes
|
||||
|
||||
- Bounded: Yes
|
||||
|
||||
* UnboundedPriorityMailbox
|
||||
|
||||
- Backed by a ``java.util.concurrent.PriorityBlockingQueue``
|
||||
|
||||
- Blocking: Yes
|
||||
|
||||
- Bounded: No
|
||||
|
||||
* BoundedPriorityMailbox
|
||||
|
||||
- Backed by a ``java.util.PriorityBlockingQueue`` wrapped in an ``akka.util.BoundedBlockingQueue``
|
||||
|
||||
- Blocking: Yes
|
||||
|
||||
- Bounded: Yes
|
||||
|
||||
* Durable mailboxes, see :ref:`durable-mailboxes-java`.
|
||||
|
||||
Mailbox configuration examples
|
||||
------------------------------
|
||||
|
||||
How to create a PriorityMailbox:
|
||||
|
||||
.. includecode:: ../java/code/docs/dispatcher/DispatcherDocTest.java#prio-mailbox
|
||||
|
||||
And then add it to the configuration:
|
||||
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#prio-dispatcher-config
|
||||
|
||||
And then an example on how you would use it:
|
||||
|
||||
.. includecode:: ../java/code/docs/dispatcher/DispatcherDocTest.java#prio-dispatcher
|
||||
|
||||
It is also possible to configure a mailbox type directly like this:
|
||||
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala
|
||||
:include: prio-mailbox-config-java,mailbox-deployment-config
|
||||
|
||||
And then use it either from deployment like this:
|
||||
|
||||
.. includecode:: code/docs/dispatcher/DispatcherDocTest.java#defining-mailbox-in-config
|
||||
|
||||
Or code like this:
|
||||
|
||||
.. includecode:: code/docs/dispatcher/DispatcherDocTest.java#defining-mailbox-in-code
|
||||
|
||||
|
||||
Requiring a message queue type for an Actor
|
||||
-------------------------------------------
|
||||
|
||||
It is possible to require a certain type of message queue for a certain type of actor
|
||||
by having that actor implement the parameterized interface :class:`RequiresMessageQueue`. Here is
|
||||
an example:
|
||||
|
||||
.. includecode:: code/docs/actor/MyBoundedUntypedActor.java#my-bounded-untyped-actor
|
||||
|
||||
The type parameter to the :class:`RequiresMessageQueue` interface needs to be mapped to a mailbox in
|
||||
configuration like this:
|
||||
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala
|
||||
:include: bounded-mailbox-config,required-mailbox-config
|
||||
|
||||
Now every time you create an actor of type :class:`MyBoundedUntypedActor` it will try to get a bounded
|
||||
mailbox. If the actor has a different mailbox configured in deployment, either directly or via
|
||||
a dispatcher with a specified mailbox type, then that will override this mapping.
|
||||
|
||||
.. note::
|
||||
|
||||
The type of the queue in the mailbox created for an actor will be checked against the required type in the
|
||||
interface and if the queue doesn't implement the required type then actor creation will fail.
|
||||
|
||||
|
||||
Mailbox configuration precedence
|
||||
--------------------------------
|
||||
|
||||
The order of precedence for the mailbox type of an actor, where lower numbers override higher, is:
|
||||
|
||||
1. Mailbox type configured in the deployment of the actor
|
||||
2. Mailbox type configured on the dispatcher of the actor
|
||||
3. Mailbox type configured on the Props of the actor
|
||||
4. Mailbox type configured via message queue requirement
|
||||
|
||||
|
||||
Creating your own Mailbox type
|
||||
------------------------------
|
||||
|
||||
An example is worth a thousand quacks:
|
||||
|
||||
.. includecode:: code/docs/dispatcher/DispatcherDocTest.java#imports-custom
|
||||
|
||||
.. includecode:: code/docs/dispatcher/DispatcherDocTest.java#mailbox-implementation-example
|
||||
|
||||
And then you just specify the FQCN of your MailboxType as the value of the "mailbox-type" in the dispatcher
|
||||
configuration, or the mailbox configuration.
|
||||
|
||||
.. note::
|
||||
|
||||
Make sure to include a constructor which takes
|
||||
``akka.actor.ActorSystem.Settings`` and ``com.typesafe.config.Config``
|
||||
arguments, as this constructor is invoked reflectively to construct your
|
||||
mailbox type. The config passed in as second argument is that section from
|
||||
the configuration which describes the dispatcher or mailbox setting using
|
||||
this mailbox type; the mailbox type will be instantiated once for each
|
||||
dispatcher or mailbox setting using it.
|
||||
|
||||
|
||||
Special Semantics of ``system.actorOf``
|
||||
---------------------------------------
|
||||
|
||||
In order to make ``system.actorOf`` both synchronous and non-blocking while
|
||||
keeping the return type :class:`ActorRef` (and the semantics that the returned
|
||||
ref is fully functional), special handling takes place for this case. Behind
|
||||
the scenes, a hollow kind of actor reference is constructed, which is sent to
|
||||
the system’s guardian actor who actually creates the actor and its context and
|
||||
puts those inside the reference. Until that has happened, messages sent to the
|
||||
:class:`ActorRef` will be queued locally, and only upon swapping the real
|
||||
filling in will they be transferred into the real mailbox. Thus,
|
||||
|
||||
.. code-block:: scala
|
||||
|
||||
final Props props = ...
|
||||
// this actor uses MyCustomMailbox, which is assumed to be a singleton
|
||||
system.actorOf(props.withDispatcher("myCustomMailbox").tell("bang", sender);
|
||||
assert(MyCustomMailbox.getInstance().getLastEnqueued().equals("bang"));
|
||||
|
||||
will probably fail; you will have to allow for some time to pass and retry the
|
||||
check à la :meth:`TestKit.awaitCond`.
|
||||
|
||||
|
|
@ -149,10 +149,12 @@ Creating Actors with Factory Methods
|
|||
------------------------------------
|
||||
|
||||
If your UntypedActor has a constructor that takes parameters then those need to
|
||||
be part of the :class:`Props` as well, as described `above <Props>`_. But there
|
||||
be part of the :class:`Props` as well, as described `above`__. But there
|
||||
are cases when a factory method must be used, for example when the actual
|
||||
constructor arguments are determined by a dependency injection framework.
|
||||
|
||||
__ Props_
|
||||
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTest.java#import-indirect
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTest.java
|
||||
:include: creating-indirectly
|
||||
|
|
@ -691,14 +693,8 @@ behavior. Upon changing the actor's message handler, i.e., right
|
|||
before invoking ``getContext().become()`` or ``getContext().unbecome()``, all
|
||||
stashed messages can be "unstashed", thereby prepending them to the actor's
|
||||
mailbox. This way, the stashed messages can be processed in the same
|
||||
order as they have been received originally.
|
||||
|
||||
.. warning::
|
||||
|
||||
Please note that the stash can only be used together with actors
|
||||
that have a deque-based mailbox. For this, configure the
|
||||
``mailbox-type`` of the dispatcher to be a deque-based mailbox, such as
|
||||
``akka.dispatch.UnboundedDequeBasedMailbox`` (see :ref:`dispatchers-java`).
|
||||
order as they have been received originally. An actor that extends
|
||||
``UntypedActorWithStash`` will automatically get a deque-based mailbox.
|
||||
|
||||
Here is an example of the ``UntypedActorWithStash`` class in action:
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue