Merge pull request #2034 from krasserm/wip-3883-eventsourced-migration-guide-krasserm

=doc #3883 Eventsourced to Akka Persistence comparison/migration
This commit is contained in:
Roland Kuhn 2014-02-27 09:56:41 +01:00
commit fa1717eead
4 changed files with 241 additions and 3 deletions

View file

@ -20,8 +20,9 @@ communication channels with at-least-once message delivery semantics.
changes to a minimum the binary compatibility guarantee for maintenance releases does not apply to the
contents of the ``akka.persistence`` package.
Akka persistence is inspired by the `eventsourced`_ library. It follows the same concepts and architecture of
`eventsourced`_ but significantly differs on API and implementation level.
Akka persistence is inspired by and the official replacement of the `eventsourced`_ library. It follows the same
concepts and architecture of `eventsourced`_ but significantly differs on API and implementation level. See also
:ref:`migration-eventsourced-2.3`
.. _eventsourced: https://github.com/eligosource/eventsourced

View file

@ -0,0 +1,217 @@
.. _migration-eventsourced-2.3:
#######################################################
Migration Guide Eventsourced to Akka Persistence 2.3.x
#######################################################
General notes
=============
`Eventsourced`_ and Akka :ref:`persistence-scala` share many high-level concepts but strongly differ on design,
implementation and usage level. This migration guide is more a higher-level comparison of Eventsourced and Akka
Persistence rather than a sequence of low-level instructions how to transform Eventsourced application code into
Akka Persistence application code. This should provide a good starting point for a migration effort. Development
teams should consult the user documentation of both projects for further details.
.. _Eventsourced: https://github.com/eligosource/eventsourced
Scope of this migration guide is code migration, not journal migration. Journals written by Eventsourced can neither
be used directly Akka Persistence nor migrated to Akka Persistence compatible journals. Journal migration tools may
be provided in the future but do not exist at the moment.
Extensions
==========
Eventsourced and Akka Persistence are both :ref:`extending-akka-scala`.
**Eventsourced:** ``EventsourcingExtension``
- Must be explicitly created with an actor system and an application-defined journal actor as arguments.
(see `usage example <https://github.com/eligosource/eventsourced#step-1-eventsourcingextension-initialization>`_).
- `Processors <https://github.com/eligosource/eventsourced#processor>`_ and
`Channels <https://github.com/eligosource/eventsourced#channel>`_
must be created with the factory methods ``processorOf`` and ``channelOf`` defined on ``EventsourcingExtension``.
- Is a central registry of created processors and channels.
**Akka Persistence:** ``Persistence`` extension
- Must **not** be explicitly created by an application. A ``Persistence`` extension is implicitly created upon first
processor or channel creation. Journal actors are automatically created from a journal plugin configuration (see
:ref:`journal-plugin-api`).
- :ref:`processors` and :ref:`channels` can be created like any other actor with ``actorOf`` without using the
``Persistence`` extension.
- Is **not** a central registry of processors and channels.
Processors
==========
**Eventsourced:** ``Eventsourced``
- Stackable trait that adds journaling (write-ahead-logging) to actors (see processor
`definition <https://github.com/eligosource/eventsourced#step-2-event-sourced-actor-definition>`_ and
`creation <https://github.com/eligosource/eventsourced#step-3-event-sourced-actor-creation-and-recovery>`_).
Name ``Eventsourced`` caused some confusion in the past as many examples used ``Eventsourced`` processors
for *command sourcing*. See also
`this FAQ entry <https://github.com/eligosource/eventsourced/wiki/FAQ#wiki-event-sourcing-comparison>`_ for
clarification.
- Must be explicitly `recovered <https://github.com/eligosource/eventsourced#recovery>`_ using recovery methods
on ``EventsourcingExtension``. Applications are responsible for avoiding an interference of replayed messages
and new messages i.e. applications have to explicitly wait for recovery to complete. Recovery on processor
re-start is not supported out-of-the box.
- Journaling-preserving `behavior changes <https://github.com/eligosource/eventsourced#behavior-changes>`_ are
only possible with special-purpose methods ``become`` and ``unbecome``, in addition to non-journaling-preserving
behavior changes with default methods ``context.become`` and ``context.unbecome``.
- Writes messages of type ``Message`` to the journal (see processor
`usage <https://github.com/eligosource/eventsourced#step-4-event-sourced-actor-usage>`_).
`Sender references <https://github.com/eligosource/eventsourced#sender-references>`_
are not stored in the journal i.e. the sender reference of a replayed message is always ``system.deadLetters``.
- Supports `snapshots <https://github.com/eligosource/eventsourced#snapshots>`_.
- Identifiers are of type ``Int`` and must be application-defined.
- Does not support batch-writes of messages to the journal.
- Does not support stashing of messages.
**Akka Persistence:** ``Processor``
- Trait that adds journaling (write-ahead-logging) to actors (see :ref:`processors`) and used by applications for
*command sourcing*. Corresponds to ``Eventsourced`` processors in Eventsourced but is not a stackable trait.
- Automatically recovers on start and re-start, by default. :ref:`recovery` can be customized or turned off by
overriding actor life cycle hooks ``preStart`` and ``preRestart``. ``Processor`` takes care that new messages
never interfere with replayed messages. New messages are internally buffered until recovery completes.
- No special-purpose behavior change methods. Default behavior change methods ``context.become`` and
``context.unbecome`` can be used and are journaling-preserving.
- Writes messages of type ``Persistent`` to the journal (see :ref:`persistent-messages`). Corresponds to ``Message``
in Eventsourced. Sender references are written to the journal. A reply to senders must therefore be done via a
channel in order to avoid redundant replies during replay. Sender references of type ``PromiseActorRef`` are
not journaled, they are ``system.deadLetters`` on replay.
- Supports :ref:`snapshots`.
- :ref:`processor-identifiers` are of type ``String``, have a default value and can be overridden by applications.
- Supports :ref:`batch-writes`.
- Supports stashing of messages.
**Akka Persistence:** ``EventsourcedProcessor``
- Extension trait and pattern on top of ``Processor`` to support :ref:`event-sourcing`. Has no direct counterpart in
Eventsourced. Can be considered as a replacement of two processors in Eventsourced where one processor processes
commands and the other processes events that have been emitted by the command processor.
Channels
========
**Eventsourced:** ``DefaultChannel``
- Prevents redundant delivery of messages to a destination (see
`usage example <https://github.com/eligosource/eventsourced#step-5-channel-usage>`_ and
`default channel <https://github.com/eligosource/eventsourced#defaultchannel>`_).
- Is associated with a single destination actor reference. A new incarnation of the destination is not automatically
resolved by the channel. In this case a new channel must be created.
- Must be explicitly activated using methods ``deliver`` or ``recover`` defined on ``EventsourcingExtension``.
- Must be activated **after** all processors have been activated. Depending on the
`recovery <https://github.com/eligosource/eventsourced#recovery>`_ method, this is either done automatically or must
be followed by the application (see `non-blocking recovery <https://github.com/eligosource/eventsourced#non-blocking-recovery>`_).
This is necessary for a network of processors and channels to recover consistently.
- Does not redeliver messages on missing or negative delivery confirmation.
- Cannot be used standalone.
**Akka Persistence:** ``Channel``
- Prevents redundant delivery of messages to a destination (see :ref:`channels`) i.e. serves the same primary purpose
as in Eventsourced.
- Is not associated with a single destination. A destination can be specified with each ``Deliver`` request and is
referred to by an actor path. A destination path is resolved to the current destination incarnation during delivery
(via ``actorSelection``).
- Must not be explicitly activated. Also, a network of processors and channels automatically recover consistently,
even if they are distributed. This enhancement, together with improved processor recovery, makes recovery of complex
Akka Persistence applications trivial. No special recovery procedures must be run by applications.
- Redelivers messages on missing delivery confirmation (see :ref:`redelivery`). In contrast to Eventsourced, Akka
Persistence doesn't distinguish between missing and negative confirmations. It only has a notion of missing
confirmations using timeouts (which are closely related to negative confirmations as both trigger message
redelivery).
- Can be used standalone.
Persistent channels
===================
**Eventsourced:** ``ReliableChannel``
- Provides ``DefaultChannel`` functionality plus persistence and recovery from sender JVM crashes (see `ReliableChannel
<https://github.com/eligosource/eventsourced#reliablechannel>`_). Also provides message redelivery in case of missing
or negative delivery confirmations.
- Delivers next message to a destination only if previous message has been successfully delivered (flow control is
done by destination).
- Stops itself when the maximum number of redelivery attempts has been reached.
- Cannot reply on persistence.
- Can be used standalone.
**Akka Persistence:** ``PersistentChannel``
- Provides ``Channel`` functionality plus persistence and recovery from sender JVM crashes (see
:ref:`persistent-channels`). Same message redelivery features as ``Channel``.
- Redelivers unconfirmed messages concurrently to newly delivered messages. Flow control is done by channel using
a configurable minimum and maximum number of pending confirmations.
- Optionally notifies applications about messages for which the maximum number of delivery attempts has been reached
(also offered by ``Channel``).
- Can reply on persistence (= accept acknowledgement).
- Can be used standalone.
Views
=====
**Eventsourced:**
- No direct support for views. Only way to maintain a view is to use a channel and a processor as destination.
**Akka Persistence:** ``View``
- Receives the message stream written by a ``Processor`` or ``EventsourcedProcessor`` by reading it directly from the
journal (see :ref:`views`). Alternative to using channels. Useful in situations where actors shall receive a
persistent message stream in correct order without duplicates.
- Can be used in combination with :ref:`channels` for sending messages.
- Supports :ref:`snapshots`.
Serializers
===========
**Eventsourced:**
- Uses a protobuf serializer for serializing ``Message`` objects.
- Delegates to a configurable Akka serializer for serializing ``Message`` payloads.
- Delegates to a configurable, proprietary (stream) serializer for serializing snapshots.
- See `Serialization <https://github.com/eligosource/eventsourced#serialization>`_.
**Akka Persistence:**
- Uses a protobuf serializer for serializing ``Persistent`` objects.
- Delegates to a configurable Akka serializer for serializing ``Persistent`` payloads.
- Delegates to a configurable Akka serializer for serializing snapshots.
- See :ref:`custom-serialization`.
Sequence numbers
================
**Eventsourced:**
- Generated on a per-journal basis.
**Akka Persistence:**
- Generated on a per-processor basis.
Storage plugins
===============
**Eventsourced:**
- Plugin API:
`SynchronousWriteReplaySupport <http://eligosource.github.io/eventsourced/api/snapshot/#org.eligosource.eventsourced.journal.common.support.SynchronousWriteReplaySupport>`_ and
`AsynchronousWriteReplaySupport <http://eligosource.github.io/eventsourced/api/snapshot/#org.eligosource.eventsourced.journal.common.support.AsynchronousWriteReplaySupport>`_
- No separation between journal and snapshot storage plugins.
- All plugins pre-packaged with project (see `journals <https://github.com/eligosource/eventsourced#journals>`_ and
`snapshot configuration <https://github.com/eligosource/eventsourced#configuration>`_)
**Akka Persistence:**
- Plugin API: ``SyncWriteJournal``, ``AsyncWriteJournal``, ``AsyncRecovery``, ``SnapshotStore``
(see :ref:`storage-plugins`).
- Clear separation between journal and snapshot storage plugins.
- Limited number of :ref:`pre-packaged-plugins` (LevelDB journal and local snapshot store).
- Impressive list of `community plugins <http://akka.io/community/>`_.

View file

@ -10,3 +10,4 @@ Migration Guides
migration-guide-2.0.x-2.1.x
migration-guide-2.1.x-2.2.x
migration-guide-2.2.x-2.3.x
migration-guide-eventsourced-2.3.x

View file

@ -21,7 +21,8 @@ communication channels with at-least-once message delivery semantics.
contents of the ``akka.persistence`` package.
Akka persistence is inspired by and the official replacement of the `eventsourced`_ library. It follows the same
concepts and architecture of `eventsourced`_ but significantly differs on API and implementation level.
concepts and architecture of `eventsourced`_ but significantly differs on API and implementation level. See also
:ref:`migration-eventsourced-2.3`
.. _eventsourced: https://github.com/eligosource/eventsourced
@ -81,6 +82,8 @@ A ``Processor`` itself is an ``Actor`` and can therefore be instantiated with ``
.. includecode:: code/docs/persistence/PersistenceDocSpec.scala#usage
.. _recovery:
Recovery
--------
@ -295,6 +298,8 @@ If an application wants to have more control how sequence numbers are assigned t
application-specific sequence number generator and include the generated sequence numbers into the ``payload``
of ``Persistent`` messages.
.. _persistent-channels:
Persistent channels
-------------------
@ -333,6 +338,8 @@ creating the channel with the ``replyPersistent`` configuration parameter set to
With this setting, either the successfully persisted message is replied to the sender or a ``PersistenceFailure``
message. In case the latter case, the sender should re-send the message.
.. _processor-identifiers:
Identifiers
-----------
@ -344,6 +351,8 @@ a channel identifier, it should be provided as argument ``Channel.props(String)`
.. includecode:: code/docs/persistence/PersistenceDocSpec.scala#channel-id-override
.. _persistent-messages:
Persistent messages
===================
@ -490,6 +499,8 @@ In larger integration scenarios, channel destinations may be actors that submit
message broker, for example. After having successfully submitted an event, they should call ``confirm()`` on the
received ``ConfirmablePersistent`` message.
.. _batch-writes:
Batch writes
============
@ -520,6 +531,8 @@ Confirmation and deletion operations performed by :ref:`channels` are also batch
and deletion batch sizes are configurable with ``akka.persistence.journal.max-confirmation-batch-size`` and
``akka.persistence.journal.max-deletion-batch-size``, respectively.
.. _storage-plugins:
Storage plugins
===============
@ -531,6 +544,8 @@ imports:
.. includecode:: code/docs/persistence/PersistencePluginDocSpec.scala#plugin-imports
.. _journal-plugin-api:
Journal plugin API
------------------
@ -571,6 +586,8 @@ A snapshot store plugin can be activated with the following minimal configuratio
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``.
.. _pre-packaged-plugins:
Pre-packaged plugins
====================
@ -635,6 +652,8 @@ directory. This can be changed by configuration where the specified path can be
.. includecode:: code/docs/persistence/PersistencePluginDocSpec.scala#snapshot-config
.. _custom-serialization:
Custom serialization
====================