The idea is to filter the sources, replacing @<var>@ occurrences with the mapping for <var> (which is currently hard-coded). @@ -> @. In order to make this work, I had to move the doc sources one directory down (into akka-docs/rst) so that the filtered result could be in a sibling directory so that relative links (to _sphinx plugins or real code) would continue to work. While I was at it I also changed it so that WARNINGs and ERRORs are not swallowed into the debug dump anymore but printed at [warn] level (minimum). One piece of fallout is that the (online) html build is now run after the normal one, not in parallel.
116 lines
4.9 KiB
ReStructuredText
116 lines
4.9 KiB
ReStructuredText
|
|
.. _message-send-semantics:
|
|
|
|
#######################
|
|
Message send semantics
|
|
#######################
|
|
|
|
|
|
|
|
Guaranteed Delivery?
|
|
====================
|
|
|
|
Akka does *not* support guaranteed delivery.
|
|
|
|
First it is close to impossible to actually give guarantees like that,
|
|
second it is extremely costly trying to do so.
|
|
The network is inherently unreliable and there is no such thing as 100%
|
|
guarantee delivery, so it can never be guaranteed.
|
|
|
|
The question is what to guarantee. That:
|
|
|
|
1. The message is sent out on the network?
|
|
2. The message is received by the other host?
|
|
3. The message is put on the target actor's mailbox?
|
|
4. The message is applied to the target actor?
|
|
5. The message is starting to be executed by the target actor?
|
|
6. The message is finished executing by the target actor?
|
|
|
|
Each one of this have different challenges and costs.
|
|
|
|
Akka embraces distributed computing and the network and makes it explicit
|
|
through message passing, therefore it does not try to lie and emulate a
|
|
leaky abstraction. This is a model that have been used with great success
|
|
in Erlang and requires the user to model his application around. You can
|
|
read more about this approach in the `Erlang documentation`_ (section
|
|
10.9 and 10.10), Akka follows it closely.
|
|
|
|
Bottom line: you as a developer know what guarantees you need in your
|
|
application and can solve it fastest and most reliable by explicit ``ACK`` and
|
|
``RETRY`` (if you really need it, most often you don't). Using Akka's Durable
|
|
Mailboxes could help with this.
|
|
|
|
Delivery semantics
|
|
==================
|
|
|
|
At-most-once
|
|
------------
|
|
|
|
Actual transports may provide stronger semantics,
|
|
but at-most-once is the semantics you should expect.
|
|
The alternatives would be once-and-only-once, which is extremely costly,
|
|
or at-least-once which essentially requires idempotency of message processing,
|
|
which is a user-level concern.
|
|
|
|
Ordering is preserved on a per-sender basis
|
|
-------------------------------------------
|
|
|
|
Actor ``A1`` sends messages ``M1``, ``M2``, ``M3`` to ``A2``
|
|
Actor ``A3`` sends messages ``M4``, ``M5``, ``M6`` to ``A2``
|
|
|
|
This means that:
|
|
1) If ``M1`` is delivered it must be delivered before ``M2`` and ``M3``
|
|
2) If ``M2`` is delivered it must be delivered before ``M3``
|
|
3) If ``M4`` is delivered it must be delivered before ``M5`` and ``M6``
|
|
4) If ``M5`` is delivered it must be delivered before ``M6``
|
|
5) ``A2`` can see messages from ``A1`` interleaved with messages from ``A3``
|
|
6) Since there is no guaranteed delivery, none, some or all of the messages may arrive to ``A2``
|
|
|
|
.. _deadletters:
|
|
|
|
Dead Letters
|
|
============
|
|
|
|
Messages which cannot be delivered (and for which this can be ascertained) will
|
|
be delivered to a synthetic actor called ``/deadLetters``. This delivery
|
|
happens on a best-effort basis; it may fail even within the local JVM (e.g.
|
|
during actor termination). Messages sent via unreliable network transports will
|
|
be lost without turning up as dead letters.
|
|
|
|
How do I Receive Dead Letters?
|
|
------------------------------
|
|
|
|
An actor can subscribe to class :class:`akka.actor.DeadLetter` on the event
|
|
stream, see :ref:`event-stream-java` (Java) or :ref:`event-stream-scala`
|
|
(Scala) for how to do that. The subscribed actor will then receive all dead
|
|
letters published in the (local) system from that point onwards. Dead letters
|
|
are not propagated over the network, if you want to collect them in one place
|
|
you will have to subscribe one actor per network node and forward them
|
|
manually. Also consider that dead letters are generated at that node which can
|
|
determine that a send operation is failed, which for a remote send can be the
|
|
local system (if no network connection can be established) or the remote one
|
|
(if the actor you are sending to does not exist at that point in time).
|
|
|
|
What Should I Use Dead Letters For?
|
|
-----------------------------------
|
|
|
|
The dead letter service follows the same rules with respect to delivery
|
|
guarantees as all other message sends, hence it cannot be used to implement
|
|
guaranteed delivery. The main use is for debugging, especially if an actor send
|
|
does not arrive consistently (where usually inspecting the dead letters will
|
|
tell you that the sender or recipient was set wrong somewhere along the way).
|
|
|
|
Dead Letters Which are (Usually) not Worrisome
|
|
----------------------------------------------
|
|
|
|
Every time an actor does not terminate by its own decision, there is a chance
|
|
that some messages which it sends to itself are lost. There is one which
|
|
happens quite easily in complex shutdown scenarios that is usually benign:
|
|
seeing a :class:`akka.dispatch.Terminate` message dropped means that two
|
|
termination requests were given, but of course only one can succeed. In the
|
|
same vein, you might see :class:`akka.actor.Terminated` messages from children
|
|
while stopping a hierarchy of actors turning up in dead letters if the parent
|
|
is still watching the child when the parent terminates.
|
|
|
|
.. _Erlang documentation: http://www.erlang.org/faq/academic.html
|
|
|