new Cluster(id, peersopt, logStateopt)
Primary brig interface. A synchronized, crash-fault-tolerant state machine consensus layer. Implements a Raft-like protocol.
Name | Type | Attributes | Default | Description |
---|---|---|---|---|
id | buffer | Unique identifier for this node. | ||
peers | Array.<module:brig/consensus~Peer> | <optional> | [] | Peer nodes. |
logState | module:brig/log~LogState | <optional> | Initialize with the given state machine. |
- Source
Members
id
PropertiesName | Type | Description |
---|---|---|
id | string | | Unique identifier for this context. |
- Source
peers
PropertiesName | Type | Description |
---|---|---|
peers | Array.<module:brig/consensus~Peer> | Synchonized nodes. |
- Source
state
PropertiesName | Type | Description |
---|---|---|
state | module:brig/log~LogState | Underlying state machine. |
- Source
Methods
acks(x) → {number}
The number of nodes whose ackedLength
is greater than or equal to x.
Name | Type | Description |
---|---|---|
x | number | Minimum number of acks. |
- Source
- Type:
- number
addPeer(peer) → {module:brig/consensus~Peer}
Adds a peer to the cluster.
Name | Type | Description |
---|---|---|
peer | module:brig/consensus~Peer | Peer to add to cluster. |
- Source
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.
Name | Type | Description |
---|---|---|
prefixLength | number | Number of entries before current. |
leaderCommit | number | Number of commits on the leader. |
suffix | Array.<module:brig/log~LogEntry> | Entries to append. |
- Source
broadcast(payload) → {module:brig/consensus~Cluster}
Helper function for broadcasting a log entry.
Name | Type | Description |
---|---|---|
payload | object | Key-value pairs to include in log entry. |
- Source
commitLogEntries()
If the leader receives a majority of acknowledgements for a log entry, it will commit the log entry.
- Source
createProtocolMapping()
Returns a map of METHOD -> HANDLER for integrating userland transport.
returns {object.<string, function>}
- Source
getPeer(peerId) → {module:brig/consensus~Peer}
Get peer from list by ID.
Name | Type | Description |
---|---|---|
peerId | string | Identifier for the peer node. |
- Source
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.
Name | Type | Description |
---|---|---|
payload | object | Payload to be included in log entry broadcasted. |
- Source
handleLogRequest(lReq)
When a follower receives a synchronization message from the leader, it will perform the following steps:
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.
If the log is consistent, the follower will append the suffix log entries to its own log.
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.
Name | Type | Description |
---|---|---|
lReq | module:brig/messages~LogRequestMessage | Append entries request message. |
- Source
handleLogResponse(lRes)
When the leader receives a log response from a follower, it will perform the following steps:
If the synchronization is successful, the leader will update
ackedLength
andsentLength
of the follower.If the synchronization is failed, the leader will decrease
sentLength
of the follower by 1, and try again.
Name | Type | Description |
---|---|---|
lRes | module:brig/messages~LogResponseMessage | Append entries response message. |
- Source
handleReplicateLog()
When the replication timer expires, the leader will synchronize its log with all followers. The synchronization message also serves as a heartbeat message.
- Source
handleVoteRequest(vReq)
When node A receives a voting request from node B, it will perform the following steps:
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.
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.
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.
Name | Type | Description |
---|---|---|
vReq | module:brig/messages~VoteRequestMessage | Vote request message. |
- Source
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.
Name | Type | Description |
---|---|---|
vRes | module:brig/messages~VoteResponseMessage | Vote response message to handle. |
- Source
join()
Initializes consensus algorithm.
- Source
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.
Name | Type | Description |
---|---|---|
leaderId | string | Peer ID to replicate from. |
follower | module:brig/consensus~Peer | Peer to replicate to. |
- Source
resetElectionTimer()
Resets the election timeout.
- Source
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.
- Source
startHeartbeat()
Sends heartbeat messages to maintain authority and to replicate the log.
- Source
(static) getElectionTimeoutMs() → {number}
Election timeout in milliseconds plus a randomized additional time.
- Source
- Type:
- number