public final class Replicator extends java.lang.Object implements Actor, ActorLogging
The Replicator
actor takes care of direct replication and gossip based
dissemination of Conflict Free Replicated Data Types (CRDTs) to replicas in the
the cluster.
The data types must be convergent CRDTs and implement ReplicatedData
, i.e.
they provide a monotonic merge function and the state changes always converge.
You can use your own custom ReplicatedData
types, and several types are provided
by this package, such as:
GCounter
, PNCounter
LWWRegister
, Flag
GSet
, ORSet
ORMap
, ORMultiMap
, LWWMap
, PNCounterMap
For good introduction to the CRDT subject watch the The Final Causal Frontier and Eventually Consistent Data Structures talk by Sean Cribbs and and the talk by Mark Shapiro and read the excellent paper A comprehensive study of Convergent and Commutative Replicated Data Types by Mark Shapiro et. al.
The Replicator
actor must be started on each node in the cluster, or group of
nodes tagged with a specific role. It communicates with other Replicator
instances
with the same path (without address) that are running on other nodes . For convenience it
can be used with the DistributedData
extension.
== Update ==
To modify and replicate a ReplicatedData
value you send a Replicator.Update
message
to the local Replicator
.
The current data value for the key
of the Update
is passed as parameter to the modify
function of the Update
. The function is supposed to return the new value of the data, which
will then be replicated according to the given consistency level.
The modify
function is called by the Replicator
actor and must therefore be a pure
function that only uses the data parameter and stable fields from enclosing scope. It must
for example not access sender()
reference of an enclosing actor.
Update
is intended to only be sent from an actor running in same local ActorSystem
as
the Replicator
, because the modify
function is typically not serializable.
You supply a write consistency level which has the following meaning:
WriteLocal
the value will immediately only be written to the local replica,
and later disseminated with gossipWriteTo(n)
the value will immediately be written to at least n
replicas,
including the local replicaWriteMajority
the value will immediately be written to a majority of replicas, i.e.
at least N/2 + 1
replicas, where N is the number of nodes in the cluster
(or cluster role group)WriteAll
the value will immediately be written to all nodes in the cluster
(or all nodes in the cluster role group)
As reply of the Update
a Replicator.UpdateSuccess
is sent to the sender of the
Update
if the value was successfully replicated according to the supplied consistency
level within the supplied timeout. Otherwise a Replicator.UpdateFailure
subclass is
sent back. Note that a Replicator.UpdateTimeout
reply does not mean that the update completely failed
or was rolled back. It may still have been replicated to some nodes, and will eventually
be replicated to all nodes with the gossip protocol.
You will always see your own writes. For example if you send two Update
messages
changing the value of the same key
, the modify
function of the second message will
see the change that was performed by the first Update
message.
In the Update
message you can pass an optional request context, which the Replicator
does not care about, but is included in the reply messages. This is a convenient
way to pass contextual information (e.g. original sender) without having to use ask
or local correlation data structures.
== Get ==
To retrieve the current value of a data you send Replicator.Get
message to the
Replicator
. You supply a consistency level which has the following meaning:
ReadLocal
the value will only be read from the local replicaReadFrom(n)
the value will be read and merged from n
replicas,
including the local replicaReadMajority
the value will be read and merged from a majority of replicas, i.e.
at least N/2 + 1
replicas, where N is the number of nodes in the cluster
(or cluster role group)ReadAll
the value will be read and merged from all nodes in the cluster
(or all nodes in the cluster role group)
As reply of the Get
a Replicator.GetSuccess
is sent to the sender of the
Get
if the value was successfully retrieved according to the supplied consistency
level within the supplied timeout. Otherwise a Replicator.GetFailure
is sent.
If the key does not exist the reply will be Replicator.NotFound
.
You will always read your own writes. For example if you send a Update
message
followed by a Get
of the same key
the Get
will retrieve the change that was
performed by the preceding Update
message. However, the order of the reply messages are
not defined, i.e. in the previous example you may receive the GetSuccess
before
the UpdateSuccess
.
In the Get
message you can pass an optional request context in the same way as for the
Update
message, described above. For example the original sender can be passed and replied
to after receiving and transforming GetSuccess
.
== Subscribe ==
You may also register interest in change notifications by sending Replicator.Subscribe
message to the Replicator
. It will send Replicator.Changed
messages to the registered
subscriber when the data for the subscribed key is updated. Subscribers will be notified
periodically with the configured notify-subscribers-interval
, and it is also possible to
send an explicit Replicator.FlushChanges
message to the Replicator
to notify the subscribers
immediately.
The subscriber is automatically removed if the subscriber is terminated. A subscriber can
also be deregistered with the Replicator.Unsubscribe
message.
== Delete ==
A data entry can be deleted by sending a Replicator.Delete
message to the local
local Replicator
. As reply of the Delete
a Replicator.DeleteSuccess
is sent to
the sender of the Delete
if the value was successfully deleted according to the supplied
consistency level within the supplied timeout. Otherwise a Replicator.ReplicationDeleteFailure
is sent. Note that ReplicationDeleteFailure
does not mean that the delete completely failed or
was rolled back. It may still have been replicated to some nodes, and may eventually be replicated
to all nodes.
A deleted key cannot be reused again, but it is still recommended to delete unused
data entries because that reduces the replication overhead when new nodes join the cluster.
Subsequent Delete
, Update
and Get
requests will be replied with Replicator.DataDeleted
.
Subscribers will receive Replicator.DataDeleted
.
== CRDT Garbage ==
One thing that can be problematic with CRDTs is that some data types accumulate history (garbage).
For example a GCounter
keeps track of one counter per node. If a GCounter
has been updated
from one node it will associate the identifier of that node forever. That can become a problem
for long running systems with many cluster nodes being added and removed. To solve this problem
the Replicator
performs pruning of data associated with nodes that have been removed from the
cluster. Data types that need pruning have to implement RemovedNodePruning
. The pruning consists
of several steps:
maxPruningDissemination
duration has elapsed. The time measurement is stopped when any
replica is unreachable, so it should be configured to worst case in a healthy cluster.PruningInitialized
marker in the data envelope.
This is gossiped to all other nodes and they mark it as seen when they receive it.PruningInitialized
marker
the leader performs the pruning and changes the marker to PruningPerformed
so that nobody
else will redo the pruning. The data envelope with this pruning state is a CRDT itself.
The pruning is typically performed by "moving" the part of the data associated with
the removed node to the leader node. For example, a GCounter
is a Map
with the node as key
and the counts done by that node as value. When pruning the value of the removed node is
moved to the entry owned by the leader node. See RemovedNodePruning.prune(akka.cluster.UniqueAddress, akka.cluster.UniqueAddress)
.RemovedNodePruning.pruningCleanup(akka.cluster.UniqueAddress)
maxPruningDissemination
duration after pruning the last entry from the
removed node the PruningPerformed
markers in the data envelope are collapsed into a
single tombstone entry, for efficiency. Clients may continue to use old data and therefore
all data are always cleared from parts associated with tombstoned nodes. Modifier and Type | Class and Description |
---|---|
static class |
Replicator.Changed<A extends ReplicatedData>
The data value is retrieved with
Replicator.Changed.get(akka.cluster.ddata.Key<T>) using the typed key. |
static class |
Replicator.Changed$ |
static interface |
Replicator.Command<A extends ReplicatedData> |
static class |
Replicator.DataDeleted<A extends ReplicatedData> |
static class |
Replicator.DataDeleted$ |
static class |
Replicator.Delete<A extends ReplicatedData>
Send this message to the local
Replicator to delete a data value for the
given key . |
static class |
Replicator.Delete$ |
static interface |
Replicator.DeleteResponse<A extends ReplicatedData> |
static class |
Replicator.DeleteSuccess<A extends ReplicatedData> |
static class |
Replicator.DeleteSuccess$ |
static class |
Replicator.FlushChanges$
Notify subscribers of changes now, otherwise they will be notified periodically
with the configured
notify-subscribers-interval . |
static class |
Replicator.Get<A extends ReplicatedData>
Send this message to the local
Replicator to retrieve a data value for the
given key . |
static class |
Replicator.Get$ |
static class |
Replicator.GetFailure<A extends ReplicatedData>
The
Replicator.Get request could not be fulfill according to the given
consistency level and timeout . |
static class |
Replicator.GetFailure$ |
static class |
Replicator.GetKeyIds$
INTERNAL API
|
static class |
Replicator.GetKeyIdsResult
INTERNAL API
|
static class |
Replicator.GetKeyIdsResult$ |
static class |
Replicator.GetReplicaCount$
Get current number of replicas, including the local replica.
|
static class |
Replicator.GetResponse<A extends ReplicatedData> |
static class |
Replicator.GetSuccess<A extends ReplicatedData>
Reply from
Get . |
static class |
Replicator.GetSuccess$ |
static class |
Replicator.Internal$
INTERNAL API
|
static class |
Replicator.ModifyFailure<A extends ReplicatedData>
If the
modify function of the Replicator.Update throws an exception the reply message
will be this ModifyFailure message. |
static class |
Replicator.ModifyFailure$ |
static class |
Replicator.NotFound<A extends ReplicatedData> |
static class |
Replicator.NotFound$ |
static class |
Replicator.ReadAll |
static class |
Replicator.ReadAll$ |
static interface |
Replicator.ReadConsistency |
static class |
Replicator.ReadFrom |
static class |
Replicator.ReadFrom$ |
static class |
Replicator.ReadLocal$ |
static class |
Replicator.ReadMajority |
static class |
Replicator.ReadMajority$ |
static class |
Replicator.ReplicaCount
Current number of replicas.
|
static class |
Replicator.ReplicaCount$ |
static class |
Replicator.ReplicationDeleteFailure<A extends ReplicatedData> |
static class |
Replicator.ReplicationDeleteFailure$ |
static interface |
Replicator.ReplicatorMessage
Marker trait for remote messages serialized by
ReplicatorMessageSerializer . |
static class |
Replicator.StoreFailure<A extends ReplicatedData>
The local store or direct replication of the
Replicator.Update could not be fulfill according to
the given consistency level due to durable store errors. |
static class |
Replicator.StoreFailure$ |
static class |
Replicator.Subscribe<A extends ReplicatedData>
Register a subscriber that will be notified with a
Replicator.Changed message
when the value of the given key is changed. |
static class |
Replicator.Subscribe$ |
static class |
Replicator.Unsubscribe<A extends ReplicatedData>
Unregister a subscriber.
|
static class |
Replicator.Unsubscribe$ |
static class |
Replicator.Update<A extends ReplicatedData> |
static class |
Replicator.Update$ |
static class |
Replicator.UpdateFailure<A extends ReplicatedData> |
static class |
Replicator.UpdateResponse<A extends ReplicatedData> |
static class |
Replicator.UpdateSuccess<A extends ReplicatedData> |
static class |
Replicator.UpdateSuccess$ |
static class |
Replicator.UpdateTimeout<A extends ReplicatedData>
The direct replication of the
Replicator.Update could not be fulfill according to
the given consistency level and
timeout . |
static class |
Replicator.UpdateTimeout$ |
static class |
Replicator.WriteAll |
static class |
Replicator.WriteAll$ |
static interface |
Replicator.WriteConsistency |
static class |
Replicator.WriteLocal$ |
static class |
Replicator.WriteMajority |
static class |
Replicator.WriteMajority$ |
static class |
Replicator.WriteTo |
static class |
Replicator.WriteTo$ |
Actor.emptyBehavior$, Actor.ignoringBehavior$
Constructor and Description |
---|
Replicator(ReplicatorSettings settings) |
Modifier and Type | Method and Description |
---|---|
protected abstract static void |
akka$actor$Actor$_setter_$context_$eq(ActorContext x$1) |
protected abstract static void |
akka$actor$Actor$_setter_$self_$eq(ActorRef x$1) |
static void |
akka$actor$ActorLogging$$_log_$eq(LoggingAdapter x$1) |
static LoggingAdapter |
akka$actor$ActorLogging$$_log() |
long |
allReachableClockTime() |
protected static void |
aroundPostRestart(java.lang.Throwable reason) |
protected static void |
aroundPostStop() |
protected static void |
aroundPreRestart(java.lang.Throwable reason,
scala.Option<java.lang.Object> message) |
protected static void |
aroundPreStart() |
protected static void |
aroundReceive(scala.PartialFunction<java.lang.Object,scala.runtime.BoxedUnit> receive,
java.lang.Object msg) |
scala.collection.immutable.Set<java.lang.String> |
changed() |
Cancellable |
clockTask() |
Cluster |
cluster() |
ActorContext |
context()
Stores the context for this actor, including self, and sender.
|
scala.collection.immutable.Map<java.lang.String,scala.Tuple2<akka.cluster.ddata.Replicator.Internal.DataEnvelope,ByteString>> |
dataEntries() |
ByteString |
digest(akka.cluster.ddata.Replicator.Internal.DataEnvelope envelope) |
scala.collection.immutable.Set<java.lang.String> |
durable() |
ActorRef |
durableStore() |
scala.collection.immutable.Set<java.lang.String> |
durableWildcards() |
static Replicator.FlushChanges$ |
flushChanges()
Java API: The
FlushChanges instance |
scala.Option<akka.cluster.ddata.Replicator.Internal.DataEnvelope> |
getData(java.lang.String key) |
ByteString |
getDigest(java.lang.String key) |
static Replicator.GetReplicaCount$ |
getReplicaCount()
Java API: The
GetReplicaCount instance |
Cancellable |
gossipTask() |
void |
gossipTo(Address address) |
boolean |
hasDurableKeys() |
boolean |
hasSubscriber(ActorRef subscriber) |
void |
initRemovedNodePruning() |
boolean |
isDurable(java.lang.String key) |
boolean |
isLeader() |
boolean |
isLocalGet(akka.cluster.ddata.Replicator.ReadConsistency readConsistency) |
boolean |
isLocalSender() |
boolean |
isLocalUpdate(akka.cluster.ddata.Replicator.WriteConsistency writeConsistency) |
scala.Option<Address> |
leader() |
scala.PartialFunction<java.lang.Object,scala.runtime.BoxedUnit> |
load() |
static LoggingAdapter |
log() |
boolean |
matchingRole(Member m) |
long |
maxPruningDisseminationNanos() |
scala.collection.mutable.HashMap<java.lang.String,scala.collection.mutable.Set<ActorRef>> |
newSubscribers() |
scala.collection.immutable.Set<Address> |
nodes() |
scala.PartialFunction<java.lang.Object,scala.runtime.BoxedUnit> |
normalReceive() |
Cancellable |
notifyTask() |
void |
performRemovedNodePruning() |
static void |
postRestart(java.lang.Throwable reason) |
void |
postStop()
User overridable callback.
|
static void |
preRestart(java.lang.Throwable reason,
scala.Option<java.lang.Object> message) |
void |
preStart()
User overridable callback.
|
long |
previousClockTime() |
static Props |
props(ReplicatorSettings settings)
Factory method for the
Props of the Replicator actor. |
akka.cluster.ddata.Replicator.Internal.DataEnvelope |
pruningCleanupTombstoned(akka.cluster.ddata.Replicator.Internal.DataEnvelope envelope) |
akka.cluster.ddata.Replicator.Internal.DataEnvelope |
pruningCleanupTombstoned(UniqueAddress removed,
akka.cluster.ddata.Replicator.Internal.DataEnvelope envelope) |
scala.collection.immutable.Map<UniqueAddress,java.lang.Object> |
pruningPerformed() |
Cancellable |
pruningTask() |
static Replicator.ReadLocal$ |
readLocal()
Java API: The
ReadLocal instance |
scala.PartialFunction<java.lang.Object,scala.runtime.BoxedUnit> |
receive()
This defines the initial actor behavior, it must return a partial function
with the actor logic.
|
void |
receiveClockTick() |
void |
receiveDelete(Key<ReplicatedData> key,
akka.cluster.ddata.Replicator.WriteConsistency consistency) |
void |
receiveFlushChanges() |
void |
receiveGet(Key<ReplicatedData> key,
akka.cluster.ddata.Replicator.ReadConsistency consistency,
scala.Option<java.lang.Object> req) |
void |
receiveGetKeyIds() |
void |
receiveGetReplicaCount() |
void |
receiveGossip(scala.collection.immutable.Map<java.lang.String,akka.cluster.ddata.Replicator.Internal.DataEnvelope> updatedData,
boolean sendBack) |
void |
receiveGossipTick() |
void |
receiveLeaderChanged(scala.Option<Address> leaderOption,
scala.Option<java.lang.String> roleOption) |
void |
receiveMemberRemoved(Member m) |
void |
receiveMemberUp(Member m) |
void |
receiveReachable(Member m) |
void |
receiveRead(java.lang.String key) |
void |
receiveReadRepair(java.lang.String key,
akka.cluster.ddata.Replicator.Internal.DataEnvelope writeEnvelope) |
void |
receiveRemovedNodePruningTick() |
void |
receiveStatus(scala.collection.immutable.Map<java.lang.String,ByteString> otherDigests,
int chunk,
int totChunks) |
void |
receiveSubscribe(Key<ReplicatedData> key,
ActorRef subscriber) |
void |
receiveTerminated(ActorRef ref) |
void |
receiveUnreachable(Member m) |
void |
receiveUnsubscribe(Key<ReplicatedData> key,
ActorRef subscriber) |
void |
receiveUpdate(Key<ReplicatedData> key,
scala.Function1<scala.Option<ReplicatedData>,ReplicatedData> modify,
akka.cluster.ddata.Replicator.WriteConsistency writeConsistency,
scala.Option<java.lang.Object> req) |
void |
receiveWeaklyUpMemberUp(Member m) |
void |
receiveWrite(java.lang.String key,
akka.cluster.ddata.Replicator.Internal.DataEnvelope envelope) |
scala.collection.immutable.Map<UniqueAddress,java.lang.Object> |
removedNodes() |
ActorSelection |
replica(Address address) |
scala.Option<Address> |
selectRandomNode(scala.collection.immutable.IndexedSeq<Address> addresses) |
ActorRef |
self()
The 'self' field holds the ActorRef for this actor.
|
Address |
selfAddress() |
UniqueAddress |
selfUniqueAddress() |
static ActorRef |
sender() |
Serializer |
serializer() |
void |
setData(java.lang.String key,
akka.cluster.ddata.Replicator.Internal.DataEnvelope envelope) |
long |
statusCount() |
int |
statusTotChunks() |
scala.collection.mutable.HashMap<java.lang.String,scala.collection.mutable.Set<ActorRef>> |
subscribers() |
scala.collection.immutable.Map<java.lang.String,Key<ReplicatedData>> |
subscriptionKeys() |
OneForOneStrategy |
supervisorStrategy()
User overridable definition the strategy to use for supervising
child actors.
|
scala.collection.immutable.Set<UniqueAddress> |
tombstoneNodes() |
void |
tombstoneRemovedNodePruning() |
static void |
unhandled(java.lang.Object message) |
scala.collection.immutable.Set<Address> |
unreachable() |
scala.collection.immutable.Set<Address> |
weaklyUpNodes() |
scala.Option<akka.cluster.ddata.Replicator.Internal.DataEnvelope> |
write(java.lang.String key,
akka.cluster.ddata.Replicator.Internal.DataEnvelope writeEnvelope) |
static Replicator.WriteLocal$ |
writeLocal()
Java API: The
WriteLocal instance |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
aroundPostRestart, aroundPostStop, aroundPreRestart, aroundPreStart, aroundReceive, postRestart, preRestart, sender, unhandled
log
public Replicator(ReplicatorSettings settings)
public static Props props(ReplicatorSettings settings)
Props
of the Replicator
actor.settings
- (undocumented)public static Replicator.ReadLocal$ readLocal()
ReadLocal
instancepublic static Replicator.WriteLocal$ writeLocal()
WriteLocal
instancepublic static Replicator.GetReplicaCount$ getReplicaCount()
GetReplicaCount
instancepublic static Replicator.FlushChanges$ flushChanges()
FlushChanges
instancepublic static final ActorRef sender()
protected static void aroundReceive(scala.PartialFunction<java.lang.Object,scala.runtime.BoxedUnit> receive, java.lang.Object msg)
protected static void aroundPreStart()
protected static void aroundPostStop()
protected static void aroundPreRestart(java.lang.Throwable reason, scala.Option<java.lang.Object> message)
protected static void aroundPostRestart(java.lang.Throwable reason)
public static void preRestart(java.lang.Throwable reason, scala.Option<java.lang.Object> message) throws java.lang.Exception
java.lang.Exception
public static void postRestart(java.lang.Throwable reason) throws java.lang.Exception
java.lang.Exception
public static void unhandled(java.lang.Object message)
protected abstract static void akka$actor$Actor$_setter_$context_$eq(ActorContext x$1)
protected abstract static void akka$actor$Actor$_setter_$self_$eq(ActorRef x$1)
public static LoggingAdapter akka$actor$ActorLogging$$_log()
public static void akka$actor$ActorLogging$$_log_$eq(LoggingAdapter x$1)
public static LoggingAdapter log()
public ActorContext context()
Actor
forward
.
WARNING: Only valid within the Actor itself, so do not close over it and publish it to other threads!
ActorContext
is the Scala API. getContext
returns a
UntypedActorContext
, which is the Java API of the actor
context.
public final ActorRef self()
Actor
self ! message
public Cluster cluster()
public Address selfAddress()
public UniqueAddress selfUniqueAddress()
public Cancellable gossipTask()
public Cancellable notifyTask()
public Cancellable pruningTask()
public Cancellable clockTask()
public Serializer serializer()
public long maxPruningDisseminationNanos()
public boolean hasDurableKeys()
public scala.collection.immutable.Set<java.lang.String> durable()
public scala.collection.immutable.Set<java.lang.String> durableWildcards()
public ActorRef durableStore()
public scala.collection.immutable.Set<Address> nodes()
public scala.collection.immutable.Set<Address> weaklyUpNodes()
public scala.collection.immutable.Map<UniqueAddress,java.lang.Object> removedNodes()
public scala.collection.immutable.Map<UniqueAddress,java.lang.Object> pruningPerformed()
public scala.collection.immutable.Set<UniqueAddress> tombstoneNodes()
public scala.Option<Address> leader()
public boolean isLeader()
public long previousClockTime()
public long allReachableClockTime()
public scala.collection.immutable.Set<Address> unreachable()
public scala.collection.immutable.Map<java.lang.String,scala.Tuple2<akka.cluster.ddata.Replicator.Internal.DataEnvelope,ByteString>> dataEntries()
public scala.collection.immutable.Set<java.lang.String> changed()
public long statusCount()
public int statusTotChunks()
public scala.collection.mutable.HashMap<java.lang.String,scala.collection.mutable.Set<ActorRef>> subscribers()
public scala.collection.mutable.HashMap<java.lang.String,scala.collection.mutable.Set<ActorRef>> newSubscribers()
public scala.collection.immutable.Map<java.lang.String,Key<ReplicatedData>> subscriptionKeys()
public void preStart()
Actor
public void postStop()
Actor
public boolean matchingRole(Member m)
public OneForOneStrategy supervisorStrategy()
Actor
supervisorStrategy
in interface Actor
public scala.PartialFunction<java.lang.Object,scala.runtime.BoxedUnit> receive()
Actor
public scala.PartialFunction<java.lang.Object,scala.runtime.BoxedUnit> load()
public scala.PartialFunction<java.lang.Object,scala.runtime.BoxedUnit> normalReceive()
public void receiveGet(Key<ReplicatedData> key, akka.cluster.ddata.Replicator.ReadConsistency consistency, scala.Option<java.lang.Object> req)
public boolean isLocalGet(akka.cluster.ddata.Replicator.ReadConsistency readConsistency)
public void receiveRead(java.lang.String key)
public boolean isLocalSender()
public void receiveUpdate(Key<ReplicatedData> key, scala.Function1<scala.Option<ReplicatedData>,ReplicatedData> modify, akka.cluster.ddata.Replicator.WriteConsistency writeConsistency, scala.Option<java.lang.Object> req)
public boolean isDurable(java.lang.String key)
public boolean isLocalUpdate(akka.cluster.ddata.Replicator.WriteConsistency writeConsistency)
public void receiveWrite(java.lang.String key, akka.cluster.ddata.Replicator.Internal.DataEnvelope envelope)
public scala.Option<akka.cluster.ddata.Replicator.Internal.DataEnvelope> write(java.lang.String key, akka.cluster.ddata.Replicator.Internal.DataEnvelope writeEnvelope)
public void receiveReadRepair(java.lang.String key, akka.cluster.ddata.Replicator.Internal.DataEnvelope writeEnvelope)
public void receiveGetKeyIds()
public void receiveDelete(Key<ReplicatedData> key, akka.cluster.ddata.Replicator.WriteConsistency consistency)
public void setData(java.lang.String key, akka.cluster.ddata.Replicator.Internal.DataEnvelope envelope)
public ByteString getDigest(java.lang.String key)
public ByteString digest(akka.cluster.ddata.Replicator.Internal.DataEnvelope envelope)
public scala.Option<akka.cluster.ddata.Replicator.Internal.DataEnvelope> getData(java.lang.String key)
public void receiveFlushChanges()
public void receiveGossipTick()
public void gossipTo(Address address)
public scala.Option<Address> selectRandomNode(scala.collection.immutable.IndexedSeq<Address> addresses)
public ActorSelection replica(Address address)
public void receiveStatus(scala.collection.immutable.Map<java.lang.String,ByteString> otherDigests, int chunk, int totChunks)
public void receiveGossip(scala.collection.immutable.Map<java.lang.String,akka.cluster.ddata.Replicator.Internal.DataEnvelope> updatedData, boolean sendBack)
public void receiveSubscribe(Key<ReplicatedData> key, ActorRef subscriber)
public void receiveUnsubscribe(Key<ReplicatedData> key, ActorRef subscriber)
public boolean hasSubscriber(ActorRef subscriber)
public void receiveTerminated(ActorRef ref)
public void receiveWeaklyUpMemberUp(Member m)
public void receiveMemberUp(Member m)
public void receiveMemberRemoved(Member m)
public void receiveUnreachable(Member m)
public void receiveReachable(Member m)
public void receiveLeaderChanged(scala.Option<Address> leaderOption, scala.Option<java.lang.String> roleOption)
public void receiveClockTick()
public void receiveRemovedNodePruningTick()
public void initRemovedNodePruning()
public void performRemovedNodePruning()
public void tombstoneRemovedNodePruning()
public akka.cluster.ddata.Replicator.Internal.DataEnvelope pruningCleanupTombstoned(akka.cluster.ddata.Replicator.Internal.DataEnvelope envelope)
public akka.cluster.ddata.Replicator.Internal.DataEnvelope pruningCleanupTombstoned(UniqueAddress removed, akka.cluster.ddata.Replicator.Internal.DataEnvelope envelope)
public void receiveGetReplicaCount()