public class EloquentRaftAlgorithm extends java.lang.Object implements RaftAlgorithm
| Modifier and Type | Field and Description |
|---|---|
static long |
MACHINE_DOWN_TIMEOUT
A very conservative timeout that defines when we consider a machine to be down.
|
RaftTransport |
transport
The underlying transport for this raft implementation
|
DEFAULT_ELECTION_RANGE, summaryTiming| Constructor and Description |
|---|
EloquentRaftAlgorithm(RaftState state,
RaftTransport transport,
java.util.Optional<RaftLifecycle> lifecycle)
A constructor for unit tests primarily, that explicitly sets the state for Raft.
|
EloquentRaftAlgorithm(java.lang.String serverName,
RaftStateMachine stateMachine,
RaftTransport transport,
java.util.Collection<java.lang.String> quorum,
java.util.concurrent.ExecutorService raftStateThreadPool,
java.util.Optional<RaftLifecycle> lifecycle)
Create a new fixed-size Raft algorithm.
|
EloquentRaftAlgorithm(java.lang.String serverName,
RaftStateMachine stateMachine,
RaftTransport transport,
int targetClusterSize,
java.util.concurrent.ExecutorService raftStateThreadPool,
java.util.Optional<RaftLifecycle> lifecycle)
Create a new auto-resizing Raft algorithm.
|
| Modifier and Type | Method and Description |
|---|---|
boolean |
bootstrap(boolean force)
Mark this node for bootstrapping.
|
void |
broadcastAppendEntries(long now)
Send out an append entries RPC (i.e., a heartbeat) to all listeners on the transport.
|
boolean |
equals(java.lang.Object o) |
java.util.List<java.lang.String> |
errors()
Print any errors we can find in the Raft node.
|
RaftTransport |
getTransport()
This gets the RaftTransport associated with this RaftAlgorithm.
|
int |
hashCode() |
void |
heartbeat(long now)
A method to be called on every heartbeat interval.
|
boolean |
isRunning()
Check if the algorithm has already been stopped via
RaftAlgorithm.stop(boolean). |
java.util.Optional<RaftLifecycle> |
lifecycle()
Get the RaftLifecycle object that this Algorithm is registered for.
|
RaftState |
mutableState()
DANGEROUS: USE ONLY IF YOU KNOW WHAT YOU ARE DOING
get A REFERENCE TO the current Raft state.
|
RaftStateMachine |
mutableStateMachine()
DANGEROUS: USE ONLY IF YOU KNOW WHAT YOU ARE DOING
get A REFERENCE TO the current Raft state machine.
|
java.util.concurrent.CompletableFuture<EloquentRaftProto.RaftMessage> |
receiveAddServerRPC(EloquentRaftProto.AddServerRequest addServerRequest,
long now)
A request has been received to add a server to the cluster.
|
void |
receiveAppendEntriesReply(EloquentRaftProto.AppendEntriesReply reply,
long now)
We received an asynchronous heartbeat from a server.
|
void |
receiveAppendEntriesRPC(EloquentRaftProto.AppendEntriesRequest heartbeat,
java.util.function.Consumer<EloquentRaftProto.RaftMessage> replyLeader,
long now)
Receive a request to apply a transition or multiple transitions.
|
java.util.concurrent.CompletableFuture<EloquentRaftProto.RaftMessage> |
receiveApplyTransitionRPC(EloquentRaftProto.ApplyTransitionRequest transition,
long now)
Apply a transition to Raft.
|
void |
receiveBadRequest(EloquentRaftProto.RaftMessage message)
A bad RPC call was received.
|
void |
receiveInstallSnapshotReply(EloquentRaftProto.InstallSnapshotReply reply,
long now)
We received an asynchronous snapshot reply from a server.
|
void |
receiveInstallSnapshotRPC(EloquentRaftProto.InstallSnapshotRequest snapshot,
java.util.function.Consumer<EloquentRaftProto.RaftMessage> replyLeader,
long now)
Receive a snapshot request RPC call.
|
java.util.concurrent.CompletableFuture<EloquentRaftProto.RaftMessage> |
receiveRemoveServerRPC(EloquentRaftProto.RemoveServerRequest removeServerRequest,
long now)
A request has been received to remove a server to the cluster.
|
void |
receiveRequestVoteRPC(EloquentRaftProto.RequestVoteRequest voteRequest,
java.util.function.Consumer<EloquentRaftProto.RaftMessage> replyLeader,
long now)
Clearly an election has been initiated, and some candidate is requesting votes to become the new leader.
|
void |
receiveRequestVotesReply(EloquentRaftProto.RequestVoteReply reply,
long now)
We received votes from another server.
|
void |
sendAppendEntries(java.lang.String target,
long nextIndex)
Send an append entries request to a particular server.
|
java.lang.String |
serverName()
The name of this server.
|
RaftState |
state()
get A COPY OF the current Raft state.
|
void |
stop(boolean kill)
A method, called primarily from unit tests, to stop this algorithm and clean up the underlying transport,
if appropriate.
|
long |
term()
The term this node sees.
|
void |
triggerElection(long now)
Signal to the cluster that we are a candidate for an election, and we are soliciting votes
|
clone, finalize, getClass, notify, notifyAll, toString, wait, wait, waitelectionTimeoutMillisRange, heartbeatMillis, receiveMessage, receiveRPC, shutdownpublic static final long MACHINE_DOWN_TIMEOUT
public final RaftTransport transport
public EloquentRaftAlgorithm(java.lang.String serverName,
RaftStateMachine stateMachine,
RaftTransport transport,
int targetClusterSize,
java.util.concurrent.ExecutorService raftStateThreadPool,
java.util.Optional<RaftLifecycle> lifecycle)
serverName - The name of this server. This MUST be unique within a cluster.stateMachine - The state machine we are running on this Raft cluster.transport - The underlying transport. This should match the cluster name argument.targetClusterSize - The target size for the Raft cluster.raftStateThreadPool - A pool to pass to RaftState for it to usepublic EloquentRaftAlgorithm(java.lang.String serverName,
RaftStateMachine stateMachine,
RaftTransport transport,
java.util.Collection<java.lang.String> quorum,
java.util.concurrent.ExecutorService raftStateThreadPool,
java.util.Optional<RaftLifecycle> lifecycle)
serverName - The name of this server. This MUST be unique within a cluster.stateMachine - The state machine we are running on this Raft cluster.transport - The underlying transport. This should match the cluster name argument.quorum - The configuration of the voting members of the cluster. The cluster will not automatically
resize.raftStateThreadPool - A pool to pass to RaftState for it to usepublic EloquentRaftAlgorithm(RaftState state, RaftTransport transport, java.util.Optional<RaftLifecycle> lifecycle)
public RaftState state()
state in interface RaftAlgorithmpublic RaftState mutableState()
mutableState in interface RaftAlgorithmpublic RaftStateMachine mutableStateMachine()
RaftAlgorithmmutableStateMachine in interface RaftAlgorithmpublic long term()
RaftState.currentTermterm in interface RaftAlgorithmpublic java.lang.String serverName()
RaftState.serverNameserverName in interface RaftAlgorithmpublic void receiveAppendEntriesRPC(EloquentRaftProto.AppendEntriesRequest heartbeat, java.util.function.Consumer<EloquentRaftProto.RaftMessage> replyLeader, long now)
receiveAppendEntriesRPC in interface RaftAlgorithmheartbeat - The request body, doubling both as a heartbeat and a request to mutate the
state machine.replyLeader - The method for replying to the leader with an ACK of the request.now - The timestamp of the current time. In non-mock cases, this is always System.currentTimeMillis().public void receiveAppendEntriesReply(EloquentRaftProto.AppendEntriesReply reply, long now)
receiveAppendEntriesReply in interface RaftAlgorithmreply - The heartbeat ACK from the follower node.now - The timestamp of the current time. In non-mock cases, this is always System.currentTimeMillis().public void sendAppendEntries(java.lang.String target,
long nextIndex)
sendAppendEntries in interface RaftAlgorithmtarget - The server we're sending the append entries RPC to.nextIndex - The nextIndex value on the target machine.public void broadcastAppendEntries(long now)
broadcastAppendEntries in interface RaftAlgorithmnow - The current time. This is usually System.currentTimeMillis(), but can
be mocked by unit tests.public void receiveInstallSnapshotRPC(EloquentRaftProto.InstallSnapshotRequest snapshot, java.util.function.Consumer<EloquentRaftProto.RaftMessage> replyLeader, long now)
receiveInstallSnapshotRPC in interface RaftAlgorithmsnapshot - The snapshot to install.replyLeader - The method for replying to the leader with an ACK of the request.now - The timestamp of the current time. In non-mock cases, this is always System.currentTimeMillis().public void receiveInstallSnapshotReply(EloquentRaftProto.InstallSnapshotReply reply, long now)
receiveInstallSnapshotReply in interface RaftAlgorithmreply - The snapshot reply from the follower node.now - The timestamp of the current time. In non-mock cases, this is always System.currentTimeMillis().public void receiveRequestVoteRPC(EloquentRaftProto.RequestVoteRequest voteRequest, java.util.function.Consumer<EloquentRaftProto.RaftMessage> replyLeader, long now)
receiveRequestVoteRPC in interface RaftAlgorithmvoteRequest - The request for votes for a particular server.replyLeader - The method for replying to the leader with an ACK of the request.now - The timestamp of the current time. In non-mock cases, this is always System.currentTimeMillis().public void receiveRequestVotesReply(EloquentRaftProto.RequestVoteReply reply, long now)
receiveRequestVotesReply in interface RaftAlgorithmreply - The vote from the server, which we should count to see if we have a
majority.now - The timestamp of the current time. In non-mock cases, this is always System.currentTimeMillis().public void triggerElection(long now)
triggerElection in interface RaftAlgorithmpublic java.util.concurrent.CompletableFuture<EloquentRaftProto.RaftMessage> receiveAddServerRPC(EloquentRaftProto.AddServerRequest addServerRequest, long now)
A request has been received to add a server to the cluster. This is only well-defined for the leader -- if the request was not received by the leader, then it should forward to the leader.
The algorithm for this is the following:
receiveAddServerRPC in interface RaftAlgorithmaddServerRequest - The request to add the server.now - The timestamp of the current time. In non-mock cases, this is always System.currentTimeMillis().public java.util.concurrent.CompletableFuture<EloquentRaftProto.RaftMessage> receiveRemoveServerRPC(EloquentRaftProto.RemoveServerRequest removeServerRequest, long now)
receiveRemoveServerRPC in interface RaftAlgorithmremoveServerRequest - The snapshot to install.now - The timestamp of the current time. In non-mock cases, this is always System.currentTimeMillis().public java.util.concurrent.CompletableFuture<EloquentRaftProto.RaftMessage> receiveApplyTransitionRPC(EloquentRaftProto.ApplyTransitionRequest transition, long now)
receiveApplyTransitionRPC in interface RaftAlgorithmtransition - The transition to applynow - The timestamp of the current time. In non-mock cases, this is always System.currentTimeMillis().public void heartbeat(long now)
heartbeat in interface RaftAlgorithmpublic boolean bootstrap(boolean force)
RaftState.bootstrap(boolean), with
some error checks beforehand.
If this node cannot bootstrap, we return false.bootstrap in interface RaftAlgorithmpublic void stop(boolean kill)
stop in interface RaftAlgorithmkill - If true, kill the server unceremoniously, without waiting for a handoff.public boolean isRunning()
RaftAlgorithm.stop(boolean).isRunning in interface RaftAlgorithmpublic void receiveBadRequest(EloquentRaftProto.RaftMessage message)
receiveBadRequest in interface RaftAlgorithmmessage - The raw message received.public java.util.Optional<RaftLifecycle> lifecycle()
RaftAlgorithmlifecycle in interface RaftAlgorithmpublic RaftTransport getTransport()
RaftAlgorithmgetTransport in interface RaftAlgorithmpublic java.util.List<java.lang.String> errors()
public boolean equals(java.lang.Object o)
equals in class java.lang.Objectpublic int hashCode()
hashCode in class java.lang.Object