public class RaftState
extends java.lang.Object
| Modifier and Type | Class and Description |
|---|---|
static class |
RaftState.LeadershipStatus
The leadership status of the given Raft node.
|
| Modifier and Type | Field and Description |
|---|---|
java.util.Optional<java.util.Set<java.lang.String>> |
alreadyKilled
The set of servers that have timed out, but we have already removed their transient
entries.
|
long |
currentTerm
Latest term server has seen (initialized to 0 on first boot, increases monotonically.
|
long |
electionTimeoutCheckpoint
The timestamp of the last message received by this node from the leader.
|
java.util.Optional<java.util.Map<java.lang.String,java.lang.Long>> |
lastMessageTimestamp
The timestamp of the last message received from each of the servers.
|
java.util.Optional<java.lang.String> |
leader
The identity of the leader, if we know it.
|
RaftState.LeadershipStatus |
leadership
The leadership status of this node (leader / candidate / other)
|
RaftLog |
log
The Raft log.
|
java.util.Optional<java.util.Map<java.lang.String,java.lang.Long>> |
matchIndex
For each server, the index of the highest log entry known to be replicated
on server.
|
java.util.Optional<java.util.Map<java.lang.String,java.lang.Long>> |
nextIndex
For each server, the index of the next log entry to send to that server
(initialized to leader last log index + 1).
|
java.lang.String |
serverName
The name (i.e., id) of this server.
|
int |
targetClusterSize
ADDITION: the target size of the cluster, for auto-scaling.
|
java.util.Optional<java.lang.String> |
votedFor
candidateId that received vote in the current term (or null if none)
|
java.util.Set<java.lang.String> |
votesReceived
The timestamp of the last message received by this node from the leader.
|
| Constructor and Description |
|---|
RaftState(java.lang.String serverName,
RaftLog log) |
RaftState(java.lang.String serverName,
RaftLog log,
int targetClusterSize)
The straightforward constructor
|
RaftState(java.lang.String serverName,
RaftStateMachine stateMachine,
java.util.Collection<java.lang.String> clusterMembers,
java.util.concurrent.ExecutorService pool)
Create a new Raft state with the given cluster members.
|
RaftState(java.lang.String serverName,
RaftStateMachine stateMachine,
java.util.concurrent.ExecutorService pool)
Create a new Raft state with only one node -- the given argument server name.
|
RaftState(java.lang.String serverName,
RaftStateMachine stateMachine,
int targetClusterSize,
java.util.concurrent.ExecutorService pool)
Create a new Raft state with the given target cluster size.
|
| Modifier and Type | Method and Description |
|---|---|
void |
becomeCandidate()
Trigger a new election, and become a candidate.
|
void |
bootstrap() |
void |
bootstrap(boolean force)
Bootstrap this cluster by adding this node to our own list of known nodes.
|
long |
commitIndex()
Index of the highest log entry know to be committed (initialized to 0, increases
monotonically).
|
void |
commitUpTo(long commitIndex,
long now)
Commit up until a given index (inclusive).
|
RaftState |
copy()
Create a copy of the Raft state at this moment in time.
|
void |
elect(long now)
Mark this state as a leader, setting the appropriate variables.
|
boolean |
equals(java.lang.Object o) |
int |
hashCode() |
boolean |
isCandidate()
If true, we are a candidate to become leader in an election.
|
boolean |
isLeader()
If true, we [think we] are the leader.
|
java.util.Set<java.lang.String> |
killNodes(long now,
long timeout)
Get the set of dead nodes that we should clear transient entries for.
|
long |
lastApplied()
The index of the highest log entry applied to state machine (initialized to 0,
increases monotonically).
|
void |
observeLifeFrom(java.lang.String followerName,
long now)
Signal to the state that we have signs of life from a particular follower.
|
void |
receiveVoteFrom(java.lang.String voter)
Receive a vote from a particular server.
|
RaftLogEntryLocation |
reconfigure(java.util.Collection<java.lang.String> quorum,
boolean force,
long now)
This creates a new configuration log entry, and appends it.
|
RaftLogEntryLocation |
reconfigure(java.util.Collection<java.lang.String> quorum,
long now) |
void |
resetElectionTimeout(long now,
java.util.Optional<java.lang.String> leader)
Reset the election timeout.
|
void |
resetElectionTimeout(long now,
java.lang.String leader) |
void |
revive(java.lang.String node)
If we could not kill the transient state on a node, we need to revive it with this function.
|
java.util.Optional<java.lang.String> |
serverToAdd(long now,
long maxLatency)
Get the server to add to the cluster, if one should be added.
|
java.util.Optional<java.lang.String> |
serverToRemove(long now,
long timeout)
Get the server to remove from the cluster, if one should be removed.
|
void |
setCurrentTerm(long term)
Set the current term for the state.
|
boolean |
shouldTriggerElection(long now,
Span electionTimeoutMillisRange)
If true, we should trigger an election.
|
void |
stepDownFromElection()
Step down from an election -- become a simple follower.
|
RaftLogEntryLocation |
transition(byte[] transition)
Transition with only a regular transition, but no hospice member.
|
RaftLogEntryLocation |
transition(java.util.Optional<byte[]> transition,
java.util.Optional<java.lang.String> newHospiceMember)
This creates a new transition log entry, and appends it.
|
void |
voteFor(java.lang.String vote)
Vote for a particular server as the leader.
|
public final java.lang.String serverName
public final RaftLog log
public long currentTerm
public java.util.Optional<java.lang.String> votedFor
public final int targetClusterSize
public volatile RaftState.LeadershipStatus leadership
public volatile long electionTimeoutCheckpoint
public volatile java.util.Optional<java.lang.String> leader
public volatile java.util.Set<java.lang.String> votesReceived
public volatile java.util.Optional<java.util.Map<java.lang.String,java.lang.Long>> nextIndex
public volatile java.util.Optional<java.util.Map<java.lang.String,java.lang.Long>> matchIndex
public volatile java.util.Optional<java.util.Map<java.lang.String,java.lang.Long>> lastMessageTimestamp
The timestamp of the last message received from each of the servers. This value should never be absent for any server -- we initialize it optimistically.
public volatile java.util.Optional<java.util.Set<java.lang.String>> alreadyKilled
The set of servers that have timed out, but we have already removed their transient entries. This prevents us spamming the |ClearTransient| transition.
public RaftState(java.lang.String serverName,
RaftStateMachine stateMachine,
java.util.concurrent.ExecutorService pool)
public RaftState(java.lang.String serverName,
RaftStateMachine stateMachine,
int targetClusterSize,
java.util.concurrent.ExecutorService pool)
public RaftState(java.lang.String serverName,
RaftStateMachine stateMachine,
java.util.Collection<java.lang.String> clusterMembers,
java.util.concurrent.ExecutorService pool)
public RaftState(java.lang.String serverName,
RaftLog log,
int targetClusterSize)
public RaftState(java.lang.String serverName,
RaftLog log)
public long lastApplied()
public RaftState copy()
public long commitIndex()
public void bootstrap(boolean force)
public void bootstrap()
bootstrap(boolean)public void setCurrentTerm(long term)
term - The new term.currentTermpublic void observeLifeFrom(java.lang.String followerName,
long now)
lastMessageTimestamp.followerName - The name of the follower we observed life from.now - The current time. This is useful to be explicit about for mocks.public boolean isLeader()
public boolean isCandidate()
public void elect(long now)
now - The current time, so we can initialize lastMessageTimestamp.
This is mostly useful for mocks -- otherwise it should be System.currentTimeMillis().public void stepDownFromElection()
public void becomeCandidate()
public void resetElectionTimeout(long now,
java.util.Optional<java.lang.String> leader)
now - The current timestamp. Should be System.currentTimeMillis() unless we're in a mockpublic void resetElectionTimeout(long now,
java.lang.String leader)
resetElectionTimeout(long, Optional)public boolean shouldTriggerElection(long now,
Span electionTimeoutMillisRange)
now - The current time, so that we can start the timer.electionTimeoutMillisRange - The timeout before we should trigger an election, as a range.
The chosen value in this range will be fixed for a given server + term.public void voteFor(java.lang.String vote)
vote - The server we voted for.public void receiveVoteFrom(java.lang.String voter)
voter - The server that voted for us.public RaftLogEntryLocation transition(java.util.Optional<byte[]> transition, java.util.Optional<java.lang.String> newHospiceMember)
transition - the transition we'd like to add to the log.newHospiceMember - an optional new hospice member to add to the state machine.public RaftLogEntryLocation transition(byte[] transition)
transition - The transition to implement.public void commitUpTo(long commitIndex,
long now)
commitIndex - The index to commit up to.now - The current time.public RaftLogEntryLocation reconfigure(java.util.Collection<java.lang.String> quorum, boolean force, long now)
quorum - the new quorum of nodes we'd like to have in the cluster.force - force the new configuration, even through it's an error.now - The current timestamp.public RaftLogEntryLocation reconfigure(java.util.Collection<java.lang.String> quorum, long now)
reconfigure(Collection, boolean, long)public java.util.Optional<java.lang.String> serverToAdd(long now,
long maxLatency)
Optional.empty().
A server should be added if all of:
targetClusterSize is nonnegative, andtargetClusterSize.now - The current time in millis. This should be a value relative to lastMessageTimestamp -- usually
the time on the transport (itself usually machine-local time).maxLatency - The maximum amount of time that we tolerate, in milliseconds, of the last heartbeat we received
from the node we're adding.Optional.empty() if none should / can be added.public java.util.Optional<java.lang.String> serverToRemove(long now,
long timeout)
Optional.empty().
A server should be removed if both:
targetClusterSize is nonnegative, andtargetClusterSize, ornow - The current time in millis. This should be a value relative to lastMessageTimestamp -- usually
the time on the transport (itself usually machine-local time).timeout - The maximum amount of time, in milliseconds, to keep a node in the configuration
before removing it from the cluster.Optional.empty() if none should be removed.public java.util.Set<java.lang.String> killNodes(long now,
long timeout)
KeyValueStateMachine where the notion of ownership
exists.now - The current time in millis. This should be a value relative to lastMessageTimestamp -- usually
the time on the transport (itself usually machine-local time).timeout - The maximum amount of time, in milliseconds, to keep a node "alive"
before clearing it's transient state from the Raft state.public void revive(java.lang.String node)
node - The node we have revived.killNodes(long, long)public boolean equals(java.lang.Object o)
equals in class java.lang.Objectpublic int hashCode()
hashCode in class java.lang.Object