!per #3652 Custom snapshot and persistent message serialization
- Protobuf serializer for Persistent message - Configurable serializer for Persistent message's payload - Configurable serializer for snapshots
This commit is contained in:
parent
6f89d346ec
commit
2a30399a29
35 changed files with 4049 additions and 390 deletions
|
|
@ -1,3 +1,7 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package docs.persistence
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package docs.persistence
|
||||
|
||||
//#plugin-imports
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package docs.persistence
|
||||
|
||||
import com.typesafe.config._
|
||||
|
||||
import org.scalatest.WordSpec
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import akka.serialization.{ Serializer, SerializationExtension }
|
||||
|
||||
class PersistenceSerializerDocSpec extends WordSpec {
|
||||
|
||||
val customSerializerConfig =
|
||||
"""
|
||||
//#custom-serializer-config
|
||||
akka.actor {
|
||||
serializers {
|
||||
my-payload = "docs.persistence.MyPayloadSerializer"
|
||||
my-snapshot = "docs.persistence.MySnapshotSerializer"
|
||||
}
|
||||
serialization-bindings {
|
||||
"docs.persistence.MyPayload" = my-payload
|
||||
"docs.persistence.MySnapshot" = my-snapshot
|
||||
}
|
||||
}
|
||||
//#custom-serializer-config
|
||||
""".stripMargin
|
||||
|
||||
SerializationExtension(ActorSystem("doc", ConfigFactory.parseString(customSerializerConfig)))
|
||||
}
|
||||
|
||||
class MyPayload
|
||||
class MySnapshot
|
||||
|
||||
class MyPayloadSerializer extends Serializer {
|
||||
def identifier: Int = 77124
|
||||
def includeManifest: Boolean = false
|
||||
def toBinary(o: AnyRef): Array[Byte] = ???
|
||||
def fromBinary(bytes: Array[Byte], manifest: Option[Class[_]]): AnyRef = ???
|
||||
}
|
||||
|
||||
class MySnapshotSerializer extends Serializer {
|
||||
def identifier: Int = 77125
|
||||
def includeManifest: Boolean = false
|
||||
def toBinary(o: AnyRef): Array[Byte] = ???
|
||||
def fromBinary(bytes: Array[Byte], manifest: Option[Class[_]]): AnyRef = ???
|
||||
}
|
||||
|
|
@ -4,9 +4,21 @@
|
|||
Persistence
|
||||
###########
|
||||
|
||||
This section describes an early access version of the Akka persistence module. Akka persistence is heavily inspired
|
||||
by the `eventsourced`_ library. It follows the same concepts and architecture of `eventsourced`_ but significantly
|
||||
differs on API and implementation level.
|
||||
Akka persistence enables stateful actors to persist their internal state so that it can be recovered when an actor
|
||||
is started, restarted by a supervisor or migrated in a cluster. It also allows stateful actors to recover from JVM
|
||||
crashes, for example. The key concept behind Akka persistence is that only changes to an actor's internal state are
|
||||
persisted but never its current state directly (except for optional snapshots). These changes are only ever appended
|
||||
to storage, nothing is ever mutated, which allows for very high transaction rates and efficient replication. Stateful
|
||||
actors are recovered by replaying stored changes to these actors from which they can rebuild internal state. This can
|
||||
be either the full history of changes or starting from a snapshot of internal actor state which can dramatically
|
||||
reduce recovery times.
|
||||
|
||||
Storage backends for state changes and snapshots are pluggable in Akka persistence. Currently, these are written to
|
||||
the local filesystem. Distributed and replicated storage, with the possibility of scaling writes, will be available
|
||||
soon.
|
||||
|
||||
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.
|
||||
|
||||
.. warning::
|
||||
|
||||
|
|
@ -27,13 +39,20 @@ Akka persistence is a separate jar file. Make sure that you have the following d
|
|||
Architecture
|
||||
============
|
||||
|
||||
* *Processor*: A processor is a persistent actor. Messages sent to a processor are written to a journal before
|
||||
its ``receive`` method is called. When a processor is started or restarted, journaled messages are replayed
|
||||
* *Processor*: A processor is a persistent, stateful actor. Messages sent to a processor are written to a journal
|
||||
before its ``receive`` method is called. When a processor is started or restarted, journaled messages are replayed
|
||||
to that processor, so that it can recover internal state from these messages.
|
||||
|
||||
* *Channel*: Channels are used by processors to communicate with other actors. They prevent that replayed messages
|
||||
are redundantly delivered to these actors.
|
||||
|
||||
* *Journal*: A journal stores the sequence of messages sent to a processor. An application can control which messages
|
||||
are stored and which are received by the processor without being journaled. The storage backend of a journal is
|
||||
pluggable.
|
||||
|
||||
* *Snapshot store*: A snapshot store persists snapshots of a processor's internal state. Snapshots are used for
|
||||
optimizing recovery times. The storage backend of a snapshot store is pluggable.
|
||||
|
||||
Use cases
|
||||
=========
|
||||
|
||||
|
|
@ -65,9 +84,10 @@ A processor can be implemented by extending the ``Processor`` trait and implemen
|
|||
Processors only write messages of type ``Persistent`` to the journal, others are received without being persisted.
|
||||
When a processor's ``receive`` method is called with a ``Persistent`` message it can safely assume that this message
|
||||
has been successfully written to the journal. If a journal fails to write a ``Persistent`` message then the processor
|
||||
receives a ``PersistenceFailure`` message instead of a ``Persistent`` message. In this case, a processor may want to
|
||||
inform the sender about the failure, so that the sender can re-send the message, if needed, under the assumption that
|
||||
the journal recovered from a temporary failure.
|
||||
is stopped, by default. If an application wants that a processors continues to run on persistence failures it must
|
||||
handle ``PersistenceFailure`` messages. In this case, a processor may want to inform the sender about the failure,
|
||||
so that the sender can re-send the message, if needed, under the assumption that the journal recovered from a
|
||||
temporary failure.
|
||||
|
||||
A ``Processor`` itself is an ``Actor`` and can therefore be instantiated with ``actorOf``.
|
||||
|
||||
|
|
@ -312,6 +332,22 @@ 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``.
|
||||
|
||||
Custom serialization
|
||||
====================
|
||||
|
||||
Serialization of snapshots and payloads of ``Persistent`` messages is configurable with Akka's
|
||||
:ref:`serialization-scala` infrastructure. For example, if an application wants to serialize
|
||||
|
||||
* payloads of type ``MyPayload`` with a custom ``MyPayloadSerializer`` and
|
||||
* snapshots of type ``MySnapshot`` with a custom ``MySnapshotSerializer``
|
||||
|
||||
it must add
|
||||
|
||||
.. includecode:: code/docs/persistence/PersistenceSerializerDocSpec.scala#custom-serializer-config
|
||||
|
||||
to the application configuration. If not specified, a default serializer is used, which is the ``JavaSerializer``
|
||||
in this example.
|
||||
|
||||
Miscellaneous
|
||||
=============
|
||||
|
||||
|
|
@ -326,6 +362,5 @@ Upcoming features
|
|||
=================
|
||||
|
||||
* Reliable channels
|
||||
* Custom serialization of messages and snapshots
|
||||
* Extended deletion of messages and snapshots
|
||||
* ...
|
||||
|
|
|
|||
|
|
@ -155,19 +155,7 @@ There is also a default remote address which is the one used by cluster support
|
|||
Deep serialization of Actors
|
||||
----------------------------
|
||||
|
||||
The current recommended approach to do deep serialization of internal actor state is to use Event Sourcing,
|
||||
for more reading on the topic, see these examples:
|
||||
|
||||
`Martin Krasser on EventSourcing Part1 <http://krasserm.blogspot.com/2011/11/building-event-sourced-web-application.html>`_
|
||||
|
||||
`Martin Krasser on EventSourcing Part2 <http://krasserm.blogspot.com/2012/01/building-event-sourced-web-application.html>`_
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Built-in API support for persisting Actors will come in a later release, see the roadmap for more info:
|
||||
|
||||
`Akka 2.0 roadmap <https://docs.google.com/a/typesafe.com/document/d/18W9-fKs55wiFNjXL9q50PYOnR7-nnsImzJqHOPPbM4E>`_
|
||||
The recommended approach to do deep serialization of internal actor state is to use Akka :ref:`persistence`.
|
||||
|
||||
A Word About Java Serialization
|
||||
===============================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue