use std::time::Duration;
use openraft::SnapshotPolicy;
#[derive(Debug, Clone)]
pub struct ConsensusConfig {
pub cluster_name: String,
pub election_timeout_min_ms: u64,
pub election_timeout_max_ms: u64,
pub heartbeat_interval_ms: u64,
pub snapshot_logs_since_last: u64,
pub max_payload_entries: u64,
pub rpc_timeout: Duration,
pub snapshot_timeout: Duration,
}
impl Default for ConsensusConfig {
fn default() -> Self {
Self {
cluster_name: "zlayer".to_string(),
election_timeout_min_ms: 1500,
election_timeout_max_ms: 3000,
heartbeat_interval_ms: 200,
snapshot_logs_since_last: 10_000,
max_payload_entries: 300,
rpc_timeout: Duration::from_secs(5),
snapshot_timeout: Duration::from_secs(60),
}
}
}
impl ConsensusConfig {
#[allow(clippy::result_large_err)]
pub fn to_openraft_config(&self) -> Result<openraft::Config, openraft::ConfigError> {
let config = openraft::Config {
cluster_name: self.cluster_name.clone(),
election_timeout_min: self.election_timeout_min_ms,
election_timeout_max: self.election_timeout_max_ms,
heartbeat_interval: self.heartbeat_interval_ms,
max_payload_entries: self.max_payload_entries,
snapshot_policy: SnapshotPolicy::LogsSinceLast(self.snapshot_logs_since_last),
enable_tick: true,
enable_heartbeat: true,
enable_elect: true,
..Default::default()
};
config.validate()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_config_validates() {
let config = ConsensusConfig::default();
let raft_config = config.to_openraft_config();
assert!(
raft_config.is_ok(),
"Default config should validate: {raft_config:?}"
);
}
#[test]
fn invalid_config_detected() {
let config = ConsensusConfig {
election_timeout_min_ms: 5000,
election_timeout_max_ms: 1000, ..Default::default()
};
assert!(config.to_openraft_config().is_err());
}
}