Merge branch 'master' into wip-query-2.5

This commit is contained in:
Konrad `ktoso` Malawski 2017-01-03 17:04:48 +01:00 committed by GitHub
commit 067b569f85
78 changed files with 1762 additions and 1744 deletions

View file

@ -1,8 +1,11 @@
.. _actordsl-scala:
################
Actor DSL
################
Actor DSL
#########
.. warning::
Actor DSL is deprecated and will be removed in the near future.
Use plain ``system.actorOf`` or ``context.actorOf`` instead.
The Actor DSL
=============
@ -77,4 +80,4 @@ runtime erased type is just an anonymous subtype of ``Act``). The purpose is to
automatically use the appropriate deque-based mailbox type required by :class:`Stash`.
If you want to use this magic, simply extend :class:`ActWithStash`:
.. includecode:: ../../../akka-actor-tests/src/test/scala/akka/actor/ActorDSLSpec.scala#act-with-stash
.. includecode:: ../../../akka-actor-tests/src/test/scala/akka/actor/ActorDSLSpec.scala#act-with-stash

View file

@ -94,9 +94,7 @@ Dangerous Variants
This method is not recommended to be used within another actor because it
encourages to close over the enclosing scope, resulting in non-serializable
:class:`Props` and possibly race conditions (breaking the actor encapsulation).
We will provide a macro-based solution in a future release which allows similar
syntax without the headaches, at which point this variant will be properly
deprecated. On the other hand using this variant in a :class:`Props` factory in
On the other hand using this variant in a :class:`Props` factory in
the actors companion object as documented under “Recommended Practices” below
is completely fine.

View file

@ -607,7 +607,7 @@ Router Example with Pool of Remote Deployed Routees
Let's take a look at how to use a cluster aware router on single master node that creates
and deploys workers. To keep track of a single master we use the :ref:`cluster-singleton-scala`
in the contrib module. The ``ClusterSingletonManager`` is started on each node.
in the cluster-tools module. The ``ClusterSingletonManager`` is started on each node.
.. includecode:: ../../../akka-samples/akka-sample-cluster-scala/src/main/scala/sample/cluster/stats/StatsSampleOneMaster.scala#create-singleton-manager

View file

@ -423,29 +423,4 @@ object PersistenceDocSpec {
//#safe-shutdown-example-good
}
object View {
import akka.actor.Props
val system: ActorSystem = ???
//#view
class MyView extends PersistentView {
override def persistenceId: String = "some-persistence-id"
override def viewId: String = "some-persistence-id-view"
def receive: Receive = {
case payload if isPersistent =>
// handle message from journal...
case payload =>
// handle message from user-land...
}
}
//#view
//#view-update
val view = system.actorOf(Props[MyView])
view ! Update(await = true)
//#view-update
}
}

View file

@ -243,6 +243,16 @@ And the ``eventsByTag`` could be backed by such an Actor for example:
.. includecode:: code/docs/persistence/query/MyEventsByTagPublisher.scala#events-by-tag-publisher
The ``ReadJournalProvider`` class must have a constructor with one of these signatures:
* constructor with a ``ExtendedActorSystem`` parameter, a ``com.typesafe.config.Config`` parameter, and a ``String`` parameter for the config path
* constructor with a ``ExtendedActorSystem`` parameter, and a ``com.typesafe.config.Config`` parameter
* constructor with one ``ExtendedActorSystem`` parameter
* constructor without parameters
The plugin section of the actor system's config will be passed in the config constructor parameter. The config path
of the plugin is passed in the ``String`` parameter.
If the underlying datastore only supports queries that are completed when they reach the
end of the "result set", the journal has to submit new queries after a while in order
to support "infinite" event streams that include events stored after the initial query

View file

@ -504,88 +504,6 @@ For example, if you configure the replay filter for leveldb plugin, it looks lik
mode = repair-by-discard-old
}
.. _persistent-views:
Persistent Views
================
.. warning::
``PersistentView`` is deprecated. Use :ref:`persistence-query-scala` instead. The corresponding
query type is ``EventsByPersistenceId``. There are several alternatives for connecting the ``Source``
to an actor corresponding to a previous ``PersistentView`` actor:
* `Sink.actorRef`_ is simple, but has the disadvantage that there is no back-pressure signal from the
destination actor, i.e. if the actor is not consuming the messages fast enough the mailbox of the actor will grow
* `mapAsync`_ combined with :ref:`actors-ask-lambda` is almost as simple with the advantage of back-pressure
being propagated all the way
* `ActorSubscriber`_ in case you need more fine grained control
The consuming actor may be a plain ``Actor`` or a ``PersistentActor`` if it needs to store its
own state (e.g. fromSequenceNr offset).
.. _Sink.actorRef: http://doc.akka.io/docs/akka-stream-and-http-experimental/1.0/scala/stream-integrations.html#Sink_actorRef
.. _mapAsync: http://doc.akka.io/docs/akka-stream-and-http-experimental/1.0/stages-overview.html#Asynchronous_processing_stages
.. _ActorSubscriber: http://doc.akka.io/docs/akka-stream-and-http-experimental/1.0/scala/stream-integrations.html#ActorSubscriber
Persistent views can be implemented by extending the ``PersistentView`` trait and implementing the ``receive`` and the ``persistenceId``
methods.
.. includecode:: code/docs/persistence/PersistenceDocSpec.scala#view
The ``persistenceId`` identifies the persistent actor from which the view receives journaled messages. It is not necessary that
the referenced persistent actor is actually running. Views read messages from a persistent actor's journal directly. When a
persistent actor is started later and begins to write new messages, by default the corresponding view is updated automatically.
It is possible to determine if a message was sent from the Journal or from another actor in user-land by calling the ``isPersistent``
method. Having that said, very often you don't need this information at all and can simply apply the same logic to both cases
(skip the ``if isPersistent`` check).
Updates
-------
The default update interval of all views of an actor system is configurable:
.. includecode:: code/docs/persistence/PersistenceDocSpec.scala#auto-update-interval
``PersistentView`` implementation classes may also override the ``autoUpdateInterval`` method to return a custom update
interval for a specific view class or view instance. Applications may also trigger additional updates at
any time by sending a view an ``Update`` message.
.. includecode:: code/docs/persistence/PersistenceDocSpec.scala#view-update
If the ``await`` parameter is set to ``true``, messages that follow the ``Update`` request are processed when the
incremental message replay, triggered by that update request, completed. If set to ``false`` (default), messages
following the update request may interleave with the replayed message stream. Automated updates always run with
``await = false``.
Automated updates of all persistent views of an actor system can be turned off by configuration:
.. includecode:: code/docs/persistence/PersistenceDocSpec.scala#auto-update
Implementation classes may override the configured default value by overriding the ``autoUpdate`` method. To
limit the number of replayed messages per update request, applications can configure a custom
``akka.persistence.view.auto-update-replay-max`` value or override the ``autoUpdateReplayMax`` method. The number
of replayed messages for manual updates can be limited with the ``replayMax`` parameter of the ``Update`` message.
Recovery
--------
Initial recovery of persistent views works the very same way as for persistent actors (i.e. by sending a ``Recover`` message
to self). The maximum number of replayed messages during initial recovery is determined by ``autoUpdateReplayMax``.
Further possibilities to customize initial recovery are explained in section :ref:`recovery-scala`.
.. _persistence-identifiers:
Identifiers
-----------
A persistent view must have an identifier that doesn't change across different actor incarnations.
The identifier must be defined with the ``viewId`` method.
The ``viewId`` must differ from the referenced ``persistenceId``, unless :ref:`snapshots` of a view and its
persistent actor should be shared (which is what applications usually do not want).
.. _snapshots:
Snapshots
@ -937,15 +855,21 @@ A journal plugin can be activated with the following minimal configuration:
.. includecode:: code/docs/persistence/PersistencePluginDocSpec.scala#journal-plugin-config
The specified plugin ``class`` must have a no-arg constructor. The ``plugin-dispatcher`` is the dispatcher
used for the plugin actor. If not specified, it defaults to ``akka.persistence.dispatchers.default-plugin-dispatcher``.
The journal plugin instance is an actor so the methods corresponding to requests from persistent actors
are executed sequentially. It may delegate to asynchronous libraries, spawn futures, or delegate to other
actors to achive parallelism.
The journal plugin class must have a constructor without parameters or a constructor with one ``com.typesafe.config.Config``
parameter. The plugin section of the actor system's config will be passed in the config constructor parameter.
The journal plugin class must have a constructor with one of these signatures:
* constructor with one ``com.typesafe.config.Config`` parameter and a ``String`` parameter for the config path
* constructor with one ``com.typesafe.config.Config`` parameter
* constructor without parameters
The plugin section of the actor system's config will be passed in the config constructor parameter. The config path
of the plugin is passed in the ``String`` parameter.
The ``plugin-dispatcher`` is the dispatcher used for the plugin actor. If not specified, it defaults to
``akka.persistence.dispatchers.default-plugin-dispatcher``.
Don't run journal tasks/futures on the system default dispatcher, since that might starve other tasks.
@ -960,15 +884,21 @@ A snapshot store plugin can be activated with the following minimal configuratio
.. includecode:: code/docs/persistence/PersistencePluginDocSpec.scala#snapshot-store-plugin-config
The specified plugin ``class`` must have a no-arg constructor. The ``plugin-dispatcher`` is the dispatcher
used for the plugin actor. If not specified, it defaults to ``akka.persistence.dispatchers.default-plugin-dispatcher``.
The snapshot store instance is an actor so the methods corresponding to requests from persistent actors
are executed sequentially. It may delegate to asynchronous libraries, spawn futures, or delegate to other
actors to achive parallelism.
The snapshot store plugin class must have a constructor without parameters or a constructor with one ``com.typesafe.config.Config``
parameter. The plugin section of the actor system's config will be passed in the config constructor parameter.
The snapshot store plugin class must have a constructor with one of these signatures:
* constructor with one ``com.typesafe.config.Config`` parameter and a ``String`` parameter for the config path
* constructor with one ``com.typesafe.config.Config`` parameter
* constructor without parameters
The plugin section of the actor system's config will be passed in the config constructor parameter. The config path
of the plugin is passed in the ``String`` parameter.
The ``plugin-dispatcher`` is the dispatcher used for the plugin actor. If not specified, it defaults to
``akka.persistence.dispatchers.default-plugin-dispatcher``.
Don't run snapshot store tasks/futures on the system default dispatcher, since that might starve other tasks.

View file

@ -135,6 +135,15 @@ This is how a ``SerializerWithStringManifest`` looks like:
You must also bind it to a name in your :ref:`configuration` and then list which classes
that should be serialized using it.
It's recommended to throw ``java.io.NotSerializableException`` in ``fromBinary``
if the manifest is unknown. This makes it possible to introduce new message types and
send them to nodes that don't know about them. This is typically needed when performing
rolling upgrades, i.e. running a cluster with mixed versions for while.
``NotSerializableException`` is treated as a transient problem in the TCP based remoting
layer. The problem will be logged and message is dropped. Other exceptions will tear down
the TCP connection because it can be an indication of corrupt bytes from the underlying
transport.
Serializing ActorRefs
---------------------