Class CounterService
- All Implemented Interfaces:
RAFT.RoleChange, StateMachine
- Since:
- 0.2
- Author:
- Bela Ban
-
Nested Class Summary
Nested Classes -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected booleanIf true, reads can return the local counter value directly.protected RaftHandleprotected long -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprotected longprotected long_compareAndSwap(String name, long expected, long value) protected longprotected voidprotected longprotected voidprotected <T extends org.jgroups.util.Streamable>
TvoidaddRoleChangeListener(RAFT.RoleChange listener) booleanallowDirtyReads(boolean flag) byte[]apply(byte[] data, int offset, int length, boolean serialize_response) Applies a command to the state machine.protected CompletionStage<Long> asyncAddAndGet(org.jgroups.util.AsciiString name, long delta, Options opts) protected CompletionStage<Long> asyncCompareAndSwap(org.jgroups.util.AsciiString name, long expected, long value, Options opts) asyncCounter(String name) Returns anRaftAsyncCounterinstance of the counter.protected CompletionStage<Long> asyncGet(org.jgroups.util.AsciiString name) protected CompletionStage<Void> asyncSet(org.jgroups.util.AsciiString name, long value) protected <T extends org.jgroups.util.Streamable>
CompletionStage<T> asyncUpdate(org.jgroups.util.AsciiString name, org.jgroups.blocks.atomic.CounterFunction<T> function, Options options) org.jgroups.JChannelchannel()longvoiddeleteCounter(String name) Deletes a counter instance (on the coordinator)deleteCounterAsync(String name) Deletes a counter instance.voiddumpLog()static StringgetOrCreateAsyncCounter(String name, long initialValue) Returns an existing counter, or creates a new one if none exists.getOrCreateCounter(String name, long initial_value) Returns an existing counter, or creates a new one if none exists.protected CompletionStage<Void> invokeAsync(CounterService.Command command, org.jgroups.util.AsciiString name, long arg) protected CompletionStage<Long> invokeAsyncAddAndGet(org.jgroups.util.AsciiString name, long arg, Options opts) protected CompletionStage<Long> invokeAsyncAndGet(CounterService.Command command, org.jgroups.util.AsciiString name, Options opts) longlonglogSize()protected static Stringprint(CounterService.Command command, String name, int num_args, DataInput in) raftId()static StringvoidReads the contents of the state machine from an input stream.longreplTimeout(long timeout) voidroleChanged(Role role) voidsetChannel(org.jgroups.JChannel ch) voidsnapshot()toString()voidwriteContentTo(DataOutput out) Writes the contents of the state machine to an output stream.
-
Field Details
-
raft
-
repl_timeout
protected long repl_timeout -
allow_dirty_reads
protected boolean allow_dirty_readsIf true, reads can return the local counter value directly. Else, reads have to go through the leader -
counters
-
-
Constructor Details
-
CounterService
public CounterService(org.jgroups.JChannel ch)
-
-
Method Details
-
setChannel
public void setChannel(org.jgroups.JChannel ch) -
channel
public org.jgroups.JChannel channel() -
addRoleChangeListener
-
replTimeout
public long replTimeout() -
replTimeout
-
allowDirtyReads
public boolean allowDirtyReads() -
allowDirtyReads
-
lastApplied
public long lastApplied() -
commitIndex
public long commitIndex() -
snapshot
-
logSize
public long logSize() -
raftId
-
raftId
-
getOrCreateCounter
Returns an existing counter, or creates a new one if none exists. This is a cluster-wide operation which would fail if no leader is elected.- Parameters:
name- Name of the counter, different counters have to have different namesinitial_value- The initial value of a new counter if there is no existing counter. Ignored if the counter already exists- Returns:
- The counter implementation
- Throws:
Exception
-
deleteCounter
-
deleteCounterAsync
Deletes a counter instance.- Parameters:
name- The name of the counter. No-op if the counter doesn't exist- Returns:
- Returns a
CompletionStagewhich is completed when the majority reach consensus.
-
printCounters
-
apply
public byte[] apply(byte[] data, int offset, int length, boolean serialize_response) Description copied from interface:StateMachineApplies a command to the state machine.The contents of the byte[] buffer are interpreted by the state machine and serialized into the actual command. The serialization mechanism should be strict with the given intervals to avoid copying the byte buffer.
This method should never throw an exception as it could leave the protocol in an undefined state. Instead, it should serialize any exception and return the buffer for the client application to handle the exception.
- Specified by:
applyin interfaceStateMachine- Parameters:
data- The byte[] bufferoffset- The offset at which the data startslength- The length of the dataserialize_response- If true, serialize and return the response, else return null- Returns:
- A serialized response value, or null (e.g. if the method returned void)
-
writeContentTo
Description copied from interface:StateMachineWrites the contents of the state machine to an output stream.This is typically called on the leader to provide state to a new node, or a node that's lagging far behind. All the data needed to completely recover the state machine should be written to the buffer.
Synchronous Execution & Event Loop Blocking
This method is invoked synchronously by the main Raft event loop. While this method is executing, the core Raft protocol is entirely blocked. Updates to the state machine may need to be put on hold while the state is written to the output stream. Otherwise, it is not possible to guarantee a consistent view of the state machine. For an asynchronous version, check
AsyncSnapshot.Buffer Ownership & Determinism
The framework owns the
DataOutputstream. The implementation must deterministically and completely write its current state to the stream before returning, as the buffer is flushed and released immediately after the method finishes. Try to stick to the minimum data needed to restore the state machine.Optimization Recommendations
Because this method blocks the main event loop until the snapshot is fully written, users are strongly encouraged to think carefully about optimizations. To minimize the blocking time, consider maintaining a fast serialization format or utilizing internal Copy-on-Write (COW) data structures so that the actual state iteration and serialization can be performed as quickly as possible.
Failures
If an exception is thrown while taking the snapshot, we do not submit the underlying buffer to remote nodes.
- Specified by:
writeContentToin interfaceStateMachine- Parameters:
out- The output stream- Throws:
Exception- Thrown on serialization or other failure.
-
readContentFrom
Description copied from interface:StateMachineReads the contents of the state machine from an input stream.This can be the case when an InstallSnapshot RPC is used to bootstrap a new node, or a node that's lagging far behind. The parsing depends on the concrete state machine implementation, but the idea is that the stream is a sequence of commands, each of which can be passed to
StateMachine.apply(byte[], int, int, boolean).Synchronous Execution & Event Loop Blocking
This method is invoked synchronously by the main Raft event loop. While this method is executing, the core Raft protocol is entirely blocked. The node will not process incoming client requests until the restoration is fully complete. For an asynchronous version, check
AsyncSnapshot.Buffer Ownership & Determinism
The framework owns the provided
DataInputbuffer, and this ownership is released the moment this method finishes. The implementation must completely read the buffer and restore its internal state deterministically before returning. The state machine implementation may need to remove all contents before populating itself from the stream.This method is never called concurrently with invocations to
StateMachine.apply(byte[], int, int, boolean). No locking mechanism is needed in the state machine.Failures
Similar to
StateMachine.apply(byte[], int, int, boolean), exceptions must be handled carefully when restoring the state machine. If an exception is thrown, the underlying system could be left in an undefined state. You should ensure the state machine remains consistent and deterministic.- Specified by:
readContentFromin interfaceStateMachine- Parameters:
in- The input stream
-
readAndDumpSnapshot
-
dumpLog
public void dumpLog() -
dumpLogEntry
-
roleChanged
- Specified by:
roleChangedin interfaceRAFT.RoleChange
-
toString
-
asyncCounter
Returns anRaftAsyncCounterinstance of the counter.This is local operation, and it does not create the counter in the raft log.
- Parameters:
name- Name of the counter, different counters have to have different names.- Returns:
- The
RaftAsyncCounterinstance
-
getOrCreateAsyncCounter
Returns an existing counter, or creates a new one if none exists.This is a cluster-wide operation which would fail if no leader is elected.
- Parameters:
name- Name of the counter, different counters have to have different namesinitialValue- The initial value of a new counter if there is no existing counter. Ignored if the counter already exists- Returns:
- The
RaftAsyncCounterimplementation.
-
asyncGet
-
asyncSet
-
asyncAddAndGet
protected CompletionStage<Long> asyncAddAndGet(org.jgroups.util.AsciiString name, long delta, Options opts) -
asyncCompareAndSwap
protected CompletionStage<Long> asyncCompareAndSwap(org.jgroups.util.AsciiString name, long expected, long value, Options opts) -
asyncUpdate
protected <T extends org.jgroups.util.Streamable> CompletionStage<T> asyncUpdate(org.jgroups.util.AsciiString name, org.jgroups.blocks.atomic.CounterFunction<T> function, Options options) -
invokeAsyncAndGet
protected CompletionStage<Long> invokeAsyncAndGet(CounterService.Command command, org.jgroups.util.AsciiString name, Options opts) -
invokeAsyncAddAndGet
protected CompletionStage<Long> invokeAsyncAddAndGet(org.jgroups.util.AsciiString name, long arg, Options opts) -
invokeAsync
protected CompletionStage<Void> invokeAsync(CounterService.Command command, org.jgroups.util.AsciiString name, long arg) -
print
protected static String print(CounterService.Command command, String name, int num_args, DataInput in) -
_create
-
_delete
-
_get
-
_set
-
_add
-
_compareAndSwap
-
_update
protected <T extends org.jgroups.util.Streamable> T _update(String name, org.jgroups.blocks.atomic.CounterFunction<T> function)
-