polish and add general/actors
This commit is contained in:
parent
0fa4f3504c
commit
31591d4ec2
5 changed files with 134 additions and 4 deletions
|
|
@ -1,4 +1,4 @@
|
|||
.. _actor_systems:
|
||||
.. _actor-systems:
|
||||
|
||||
Actor Systems
|
||||
=============
|
||||
|
|
@ -89,7 +89,7 @@ Actor Best Practices
|
|||
special-cased thread which sends messages to the actors which shall act on
|
||||
them.
|
||||
|
||||
#. Do not pass mutable objects between actors which you actually mutate. In
|
||||
#. Do not pass between actors mutable objects which you actually mutate. In
|
||||
order to ensure that, prefer immutable messages. If the encapsulation of
|
||||
actors is broken by exposing their mutable state to the outside, you are
|
||||
back in normal Java concurrency land with all the drawbacks.
|
||||
|
|
|
|||
124
akka-docs/general/actors.rst
Normal file
124
akka-docs/general/actors.rst
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
.. _actors-general:
|
||||
|
||||
What is an Actor?
|
||||
=================
|
||||
|
||||
The previous section about :ref:`actor-systems` explained how actors form
|
||||
hierarchies and are the smallest unit when building an application. This
|
||||
section looks at one such actor in isolation, explaining the concepts you
|
||||
encounter while implementing it. For more an in depth reference with all the
|
||||
details please refer to :ref:`actors-scala` and :ref:`untyped-actors-java`.
|
||||
|
||||
An actor is a container for `State`_, `Behavior`_, a `Mailbox`_, `Children`_
|
||||
and a `Fault Handling Strategy`_. All of this is encapsulated behind an `Actor
|
||||
Reference`_.
|
||||
|
||||
Actor Reference
|
||||
---------------
|
||||
|
||||
As detailed below, an actor object needs to be shielded from the outside in
|
||||
order to benefit from the actor model. Therefore, actors are represented to the
|
||||
outside using actor references, which are objects that can be passed around
|
||||
freely and without restriction. This split into inner and outer object enables
|
||||
transparency for all the desired operations: restarting an actor without
|
||||
needing to update references elsewhere, placing the actual actor object on
|
||||
remote hosts, sending messages to actors in completely different applications.
|
||||
But the most important aspect is that it is not possible to look inside an
|
||||
actor and get hold of its state from the outside, unless the actor unwisely
|
||||
publishes this information itself.
|
||||
|
||||
State
|
||||
-----
|
||||
|
||||
Actor objects will typically contain some variables which reflect possible
|
||||
states the actor may be in. This can be an explicit state machine (e.g. using
|
||||
the :ref:`fsm` module), or it could be a counter, set of listeners, pending
|
||||
requests, etc. These data are what make an actor valuable, and they must be
|
||||
protected from corruption by other actors. The good news is that Akka actors
|
||||
conceptually each have their own light-weight thread, which is completely
|
||||
shielded from the rest of the system. This means that instead of having to
|
||||
synchronize access using locks you can just write your actor code without
|
||||
worrying about concurrency at all.
|
||||
|
||||
Behind the scenes Akka will run sets of actors on sets of real threads, where
|
||||
typically many actors share one thread, and subsequent invocations of one actor
|
||||
may end up being processed on different threads. Akka ensures that this
|
||||
implementation detail does not affect the single-threadedness of handling the
|
||||
actor’s state.
|
||||
|
||||
Because the internal state is vital to an actor’s operations, having
|
||||
inconsistent state is fatal. Thus, when the actor fails and is restarted by its
|
||||
supervisor, the state will be created from scratch, like upon first creating
|
||||
the actor. This is to enable the ability of self-healing of the system.
|
||||
|
||||
Behavior
|
||||
--------
|
||||
|
||||
Every time a message is processed, it is matched against the current behavior
|
||||
of the actor. Behavior means a function which defines the actions to be taken
|
||||
in reaction to the message at that point in time, say forward a request if the
|
||||
client is authorized, deny it otherwise. This behavior may change over time,
|
||||
e.g. because different clients obtain authorization over time, or because the
|
||||
actor may go into an “out-of-service” mode and later come back. These changes
|
||||
are achieved by either encoding them in state variables which are read from the
|
||||
behavior logic, or the function itself may be swapped out at runtime, see the
|
||||
``become`` and ``unbecome`` operations. However, the initial behavior defined
|
||||
during construction of the actor object is special in the sense that a restart
|
||||
of the actor will reset its behavior to this initial one.
|
||||
|
||||
Mailbox
|
||||
-------
|
||||
|
||||
An actor’s purpose is the processing of messages, and these messages were sent
|
||||
to the actor from other actors (or from outside the actor system). The piece
|
||||
which connects sender and receiver is the actor’s mailbox: each actor has
|
||||
exactly one mailbox to which all senders enqueue their messages. Enqueuing
|
||||
happens in the time-order of send operations, which means that messages sent
|
||||
from different actors may not have a defined order at runtime due to the
|
||||
apparent randomness of distributing actors across threads. Sending multiple
|
||||
messages to the same target from the same actor, on the other hand, will
|
||||
enqueue them in the same order.
|
||||
|
||||
There are different mailbox implementations to choose from, the default being a
|
||||
FIFO: the order of the messages processed by the actor matches the order in
|
||||
which they were enqueued. This is usually a good default, but applications may
|
||||
need to prioritize some messages over others. In this case, a priority mailbox
|
||||
will enqueue not always at the end but at a position as given by the message
|
||||
priority, which might even be at the front. While using such a queue, the order
|
||||
of messages processed will naturally be defined by the queue’s algorithm and in
|
||||
general not be FIFO.
|
||||
|
||||
An important feature in which Akka differs from some other actor model
|
||||
implementations is that the current behavior must always handle the next
|
||||
dequeued message, there is no scanning the mailbox for the next matching one.
|
||||
Failure to handle a message will typically be treated as a failure, unless this
|
||||
behavior is overridden.
|
||||
|
||||
Children
|
||||
--------
|
||||
|
||||
Each actor is potentially a supervisor: if it creates children for delegating
|
||||
sub-tasks, it will automatically supervise them. The list of children is
|
||||
maintained within the actor’s context and the actor has access to it.
|
||||
Modifications to the list are done by creating (``context.actorOf(...)``) or
|
||||
stopping (``context.stop(child)``) children and these actions are reflected
|
||||
immediately. The actual creation and termination actions happen behind the
|
||||
scenes in an asynchronous way, so they do not “block” their supervisor.
|
||||
|
||||
Fault Handling Strategy
|
||||
-----------------------
|
||||
|
||||
The final piece of an actor is its strategy for handling faults of its
|
||||
children. To keep it simple and robust, this is declared outside of the actor’s
|
||||
code and has no access to the actor’s state. Fault handling is then done
|
||||
transparently by Akka, applying one of the strategies described in
|
||||
:ref:`supervision` for each incoming failure. As this strategy is fundamental
|
||||
to how an actor system is structured, it cannot be changed once an actor has
|
||||
been created.
|
||||
|
||||
Considering that there is only one such strategy for each actor, this means
|
||||
that if different strategies apply to the various children of an actor, the
|
||||
children should be grouped beneath intermediate supervisors with matching
|
||||
strategies, preferring once more the structuring of actor systems according to
|
||||
the splitting of tasks into sub-tasks.
|
||||
|
||||
|
|
@ -4,8 +4,10 @@ General
|
|||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
actor-systems
|
||||
actors
|
||||
supervision
|
||||
addressing
|
||||
jmm
|
||||
message-send-semantics
|
||||
configuration
|
||||
addressing
|
||||
supervision
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
.. _supervision:
|
||||
|
||||
Supervision
|
||||
===========
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
.. _fsm:
|
||||
|
||||
###
|
||||
FSM
|
||||
###
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue