brig/consensus~ Cluster

new Cluster(id, peersopt, logStateopt)

Primary brig interface. A synchronized, crash-fault-tolerant state machine consensus layer. Implements a Raft-like protocol.

Parameters:
NameTypeAttributesDefaultDescription
idbuffer

Unique identifier for this node.

peersArray.<module:brig/consensus~Peer><optional>
[]

Peer nodes.

logStatemodule:brig/log~LogState<optional>

Initialize with the given state machine.

Members

id

Properties
NameTypeDescription
idstring | number

Unique identifier for this context.

peers

Properties
NameTypeDescription
peersArray.<module:brig/consensus~Peer>

Synchonized nodes.

state

Properties
NameTypeDescription
statemodule:brig/log~LogState

Underlying state machine.

Methods

acks(x) → {number}

The number of nodes whose ackedLength is greater than or equal to x.

Parameters:
NameTypeDescription
xnumber

Minimum number of acks.

Returns:
Type: 
number

addPeer(peer) → {module:brig/consensus~Peer}

Adds a peer to the cluster.

Parameters:
NameTypeDescription
peermodule:brig/consensus~Peer

Peer to add to cluster.

appendEntries(prefixLength, leaderCommit, suffix)

Appends the suffix log entries to the log of the follower. Here we check whether the follower has the same suffix log entries as the leader. If not, the follower will remove all the log entries after prefix from its log, and append the suffix log entries from leader to its log.

Parameters:
NameTypeDescription
prefixLengthnumber

Number of entries before current.

leaderCommitnumber

Number of commits on the leader.

suffixArray.<module:brig/log~LogEntry>

Entries to append.

broadcast(payload) → {module:brig/consensus~Cluster}

Helper function for broadcasting a log entry.

Parameters:
NameTypeDescription
payloadobject

Key-value pairs to include in log entry.

commitLogEntries()

If the leader receives a majority of acknowledgements for a log entry, it will commit the log entry.

createProtocolMapping()

Returns a map of METHOD -> HANDLER for integrating userland transport.

returns {object.<string, function>}

getPeer(peerId) → {module:brig/consensus~Peer}

Get peer from list by ID.

Parameters:
NameTypeDescription
peerIdstring

Identifier for the peer node.

handleBroadcast(payload)

When the application layer triggers a broadcast, the leader will append the broadcast message to its log, and send the log entry to all followers. If the current node is not a leader, it will forward the broadcast message to the leader.

Parameters:
NameTypeDescription
payloadobject

Payload to be included in log entry broadcasted.

handleLogRequest(lReq)

When a follower receives a synchronization message from the leader, it will perform the following steps:

  1. The follower will check whether the log is consistent with the log entries that the leader believes the follower has. If not, the follower will reject the synchronization request.

  2. If the log is consistent, the follower will append the suffix log entries to its own log.

  3. The follower will check whether the leader has committed any log entries. If so, the follower will commit the log entries that the leader has committed.

To check whether the log is consistent, the follower will compare the term of the last log entry in the prefix with leader’s prefix_term. If they are not equal, the log is inconsistent. It is true due to a property of Raft: if two nodes have the same log term at the same index, then they have the same log entries at and before that index. Here we don’t give the proof of this property, but you can find it in the original paper.

Parameters:
NameTypeDescription
lReqmodule:brig/messages~LogRequestMessage

Append entries request message.

handleLogResponse(lRes)

When the leader receives a log response from a follower, it will perform the following steps:

  1. If the synchronization is successful, the leader will update ackedLength and sentLength of the follower.

  2. If the synchronization is failed, the leader will decrease sentLength of the follower by 1, and try again.

Parameters:
NameTypeDescription
lResmodule:brig/messages~LogResponseMessage

Append entries response message.

handleReplicateLog()

When the replication timer expires, the leader will synchronize its log with all followers. The synchronization message also serves as a heartbeat message.

handleVoteRequest(vReq)

When node A receives a voting request from node B, it will perform the following steps:

  1. Check if the term of B is greater than or equal the current term of A. If not, A will reject the voting request, since voting for B might result in multiple leaders in B’s term.

  2. Check if the log of B is more or equal up-to-date than the log of A. If not, A will reject the voting request, since voting for B might result in log entries being lost.

  3. Check if A has already voted for another candidate in the current term. If so, A will reject the voting request, since voting for B might result in multiple leaders in the current term.

Parameters:
NameTypeDescription
vReqmodule:brig/messages~VoteRequestMessage

Vote request message.

handleVoteResponse(vRes)

Upon receiving voting responses, a node should check whether it has received a majority of votes. If so, it should transition to the role of leader. Otherwise, it should remain a candidate.

Parameters:
NameTypeDescription
vResmodule:brig/messages~VoteResponseMessage

Vote response message to handle.

join()

Initializes consensus algorithm.

replicateLog(leaderId, follower)

Helper function that synchronizes the log of the leader with a follower. The simplest way to synchronize the log is to send the entire log to the follower. However, this is inefficient. As mentioned earlier, the leader assumes that the log of the follower is the same as its own log when it becomes a leader. Therefore, the leader only needs to send the log entries that the follower does not have.

sentLength[follower] := log.length 
// the node assumes that the log of the follower is the same as its own log

The leader maintains a variable sentLength for each follower. sentLength[follower] denotes the length of the log that the leader believes the follower has. When the leader synchronizes the logs with the follower, it will send the log entries after sentLength[follower]. If the synchronization is failed, the leader will decrease sentLength[follower] by 1, and try again.

Parameters:
NameTypeDescription
leaderIdstring

Peer ID to replicate from.

followermodule:brig/consensus~Peer

Peer to replicate to.

resetElectionTimer()

Resets the election timeout.

startElection()

Each node has a election timer, which is reset when receving the heartbeat from its leader. When the Election Timer expires, the follower will transition to the role of “candidate”. Following this transition, it will proceed to send voting requests to all nodes.

startHeartbeat()

Sends heartbeat messages to maintain authority and to replicate the log.

(static) getElectionTimeoutMs() → {number}

Election timeout in milliseconds plus a randomized additional time.

Returns:
Type: 
number