Interface StreamReplicator
- All Superinterfaces:
AutoCloseable
,Closeable
,Replicator
["hello", "world"]
. The messages might be read back as ["hello",
"world"]
, ["helloworld"]
, ["he", "llowor", "ld"]
, etc.
For ensuring that messages aren't torn in the middle when a new leader is elected,
messages must be written into the replicator with properly defined boundaries. When writing
["hello", "world"]
, a leader election can cause the second message to be dropped,
and then only ["hello"]
is read. If ["helloworld"]
was written, no tearing
of the two words can occur. They might both be read or both be dropped, atomically.
StreamReplicators require that a control message acceptor be installed for supporting group membership changes. Consider using MessageReplicator
instead, although it has slightly higher overhead. In order for control
messages to be processed, replicas must be actively reading and calling controlMessageReceived
as necessary.
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic interface
Interface called by any group member for reading committed messages.static interface
Interface called by the group leader for proposing messages.Nested classes/interfaces inherited from interface org.cojen.tupl.repl.Replicator
Replicator.Accessor
-
Method Summary
Modifier and TypeMethodDescriptionvoid
controlMessageAcceptor
(Consumer<byte[]> acceptor) Install a callback to be invoked when the replicator needs to send control messages, which must propagate through the replication log.void
controlMessageReceived
(long position, byte[] message) Called to pass along a control message, which was originally provided through an acceptor.newReader
(long position, boolean follow) Returns a new reader which accesses data starting from the given position.Returns a new writer for the leader to write into, or else returns null if the local member isn't the leader.newWriter
(long position) Returns a new writer for the leader to write into, or else returns null if the local member isn't the leader.static StreamReplicator
open
(ReplicatorConfig config) Open a StreamReplicator instance, creating it if necessary.Methods inherited from interface org.cojen.tupl.repl.Replicator
commitPosition, compact, connect, encoding, failover, isReadable, localAddress, localMemberId, localRole, requestSnapshot, restore, snapshotRequestAcceptor, socketAcceptor, start, sync, syncCommit
-
Method Details
-
open
Open a StreamReplicator instance, creating it if necessary. Be sure to call thestart
method too.- Throws:
IllegalArgumentException
- if misconfiguredIOException
-
newReader
Returns a new reader which accesses data starting from the given position. The reader returns EOF whenever the end of a term is reached. At the end of a term, try to obtain a new writer to determine if the local member has become the leader.When passing true for the follow parameter, a reader is always provided at the requested position. When passing false for the follow parameter, null is returned if the current member is the leader for the given position.
Note: Reader instances are not expected to be thread-safe.
- Specified by:
newReader
in interfaceReplicator
- Parameters:
position
- position to start reading from, known to have been committedfollow
- pass true to obtain an active reader, even if local member is the leader- Returns:
- reader or possibly null when follow is false
- Throws:
InvalidReadException
- if position is lower than the start position
-
newWriter
StreamReplicator.Writer newWriter()Returns a new writer for the leader to write into, or else returns null if the local member isn't the leader. The writer stops accepting messages when the term has ended, and possibly another leader has been elected.Note: Writer instances are not expected to be thread-safe.
- Specified by:
newWriter
in interfaceReplicator
- Returns:
- writer or null if not the leader
- Throws:
IllegalStateException
- if an existing writer for the current term already exists
-
newWriter
Returns a new writer for the leader to write into, or else returns null if the local member isn't the leader. The writer stops accepting messages when the term has ended, and possibly another leader has been elected.Note: Writer instances are not expected to be thread-safe.
- Specified by:
newWriter
in interfaceReplicator
- Parameters:
position
- expected position to start writing from as leader; method returns null if the given position is lower- Returns:
- writer or null if not the leader
- Throws:
IllegalStateException
- if an existing writer for the current term already exists
-
controlMessageReceived
Called to pass along a control message, which was originally provided through an acceptor. Control messages must be passed along in the original order in which they were created. A control message cannot be treated as applied until after this method returns.- Parameters:
position
- log position just after the message- Throws:
IOException
-
controlMessageAcceptor
Install a callback to be invoked when the replicator needs to send control messages, which must propagate through the replication log. From the perspective of the acceptor, control messages should be treated as opaque. Control messages are primarily used for supporting group membership changes, and without an acceptor, members cannot be added or removed.Acceptor implementations are expected to wrap messages such that they can be propagated along with regular messages, and then later be passed to the
controlMessageReceived
method. If a control message cannot be written (possibly because the local member isn't the leader), it might be silently dropped. Implementations are not required to pass control messages to a remote leader.- Parameters:
acceptor
- acceptor to use, or pass null to disable
-