pub struct ClusterConfig {
pub voters: BTreeSet<NodeId>,
pub new_voters: BTreeSet<NodeId>,
pub non_voters: BTreeSet<NodeId>,
}Expand description
Cluster configuration (membership).
§Examples
use raftbare::{ClusterConfig, NodeId};
// Makes a new cluster configuration with two voting nodes.
let mut config = ClusterConfig::new();
config.voters.insert(NodeId::new(0));
config.voters.insert(NodeId::new(1));
assert!(!config.is_joint_consensus());
// Adds a new non-voting node.
config.non_voters.insert(NodeId::new(2));
assert!(!config.is_joint_consensus());
// Updates the configuration to add a new voting node.
config.new_voters = config.voters.clone();
config.new_voters.insert(NodeId::new(3));
assert!(config.is_joint_consensus());The config value in the example above can be applied to a cluster via Node::propose_config().
Fields§
§voters: BTreeSet<NodeId>Voting nodes.
For a cluster to be available, the majority of the voters must be alive and able to communicate with each other.
new_voters: BTreeSet<NodeId>New voting nodes during joint consensus.
When a cluster changes its configuration, it enters a joint consensus state.
In that state, voters and new_voters represent the old and new configurations, respectively.
During joint consensus, the cluster requires the majority of both the old and new voters to be available to proceed with leader election and log entry commit.
Once the log entry for this joint configuration is committed, voters takes the value of new_voters,
and the cluster exits the joint consensus state.
If new_voters is empty, it means there are no configuration changes in progress.
non_voters: BTreeSet<NodeId>Non-voting nodes.
Non-voting nodes do not participate in the leader election and log entry commit quorum, but they do replicate log entries from the leader. Additionally, non-voting nodes never transition to candidate or leader.
When adding more than half of the current number of nodes to a cluster that has a large snapshot or many log entries, it is recommended to first add the new nodes as non-voters to avoid blocking subsequent log commits. Allow these nodes to catch up with the leader before promoting them to voters.
Note that adding or removing non-voters does not require a joint consensus.
Implementations§
Source§impl ClusterConfig
impl ClusterConfig
Sourcepub fn new() -> Self
pub fn new() -> Self
Makes a new empty ClusterConfig instance.
Sourcepub fn contains(&self, id: NodeId) -> bool
pub fn contains(&self, id: NodeId) -> bool
Returns true if the given node is in this configuration.
Sourcepub fn is_joint_consensus(&self) -> bool
pub fn is_joint_consensus(&self) -> bool
Returns true if this configuration represents a joint consensus state.
Sourcepub fn unique_nodes(&self) -> impl '_ + Iterator<Item = NodeId>
pub fn unique_nodes(&self) -> impl '_ + Iterator<Item = NodeId>
Gets an iterator over all unique NodeIds in this configuration, in sorted order.
Sourcepub fn to_joint_consensus(
&self,
adding_voters: &[NodeId],
removing_voters: &[NodeId],
) -> Self
pub fn to_joint_consensus( &self, adding_voters: &[NodeId], removing_voters: &[NodeId], ) -> Self
Converts this configuration to a joint consensus by adding and removing voters.
§Examples
use raftbare::{Node, NodeId};
fn add_node(node: &mut Node, adding_node_id: NodeId) {
let new_config = node.config().to_joint_consensus(&[adding_node_id], &[]);
assert_eq!(new_config.voters.len() + 1, new_config.new_voters.len());
node.propose_config(new_config);
}
fn remove_node(node: &mut Node, removing_id: NodeId) {
let new_config = node.config().to_joint_consensus(&[], &[removing_id]);
assert_eq!(new_config.voters.len() - 1, new_config.new_voters.len());
node.propose_config(new_config);
}Trait Implementations§
Source§impl Clone for ClusterConfig
impl Clone for ClusterConfig
Source§fn clone(&self) -> ClusterConfig
fn clone(&self) -> ClusterConfig
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more