Skip to content

Commit

Permalink
config: Extract to own file. (#91)
Browse files Browse the repository at this point in the history
  • Loading branch information
A. Hobden authored Aug 1, 2018
1 parent 8a217a6 commit 935840b
Show file tree
Hide file tree
Showing 4 changed files with 214 additions and 180 deletions.
206 changes: 206 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

// Copyright 2015 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use super::{INVALID_ID, errors::{Error, Result}};
pub use super::read_only::{ReadOnlyOption, ReadState};

/// Config contains the parameters to start a raft.
pub struct Config {
/// The identity of the local raft. It cannot be 0, and must be unique in the group.
pub id: u64,

/// The IDs of all nodes (including self) in
/// the raft cluster. It should only be set when starting a new
/// raft cluster.
/// Restarting raft from previous configuration will panic if
/// peers is set.
/// peer is private and only used for testing right now.
pub peers: Vec<u64>,

/// The IDs of all learner nodes (maybe include self if
/// the local node is a learner) in the raft cluster.
/// learners only receives entries from the leader node. It does not vote
/// or promote itself.
pub learners: Vec<u64>,

/// The number of node.tick invocations that must pass between
/// elections. That is, if a follower does not receive any message from the
/// leader of current term before ElectionTick has elapsed, it will become
/// candidate and start an election. election_tick must be greater than
/// HeartbeatTick. We suggest election_tick = 10 * HeartbeatTick to avoid
/// unnecessary leader switching
pub election_tick: usize,

/// HeartbeatTick is the number of node.tick invocations that must pass between
/// heartbeats. That is, a leader sends heartbeat messages to maintain its
/// leadership every heartbeat ticks.
pub heartbeat_tick: usize,

/// Applied is the last applied index. It should only be set when restarting
/// raft. raft will not return entries to the application smaller or equal to Applied.
/// If Applied is unset when restarting, raft might return previous applied entries.
/// This is a very application dependent configuration.
pub applied: u64,

/// Limit the max size of each append message. Smaller value lowers
/// the raft recovery cost(initial probing and message lost during normal operation).
/// On the other side, it might affect the throughput during normal replication.
/// Note: math.MaxUusize64 for unlimited, 0 for at most one entry per message.
pub max_size_per_msg: u64,

/// Limit the max number of in-flight append messages during optimistic
/// replication phase. The application transportation layer usually has its own sending
/// buffer over TCP/UDP. Set to avoid overflowing that sending buffer.
/// TODO: feedback to application to limit the proposal rate?
pub max_inflight_msgs: usize,

/// Specify if the leader should check quorum activity. Leader steps down when
/// quorum is not active for an electionTimeout.
pub check_quorum: bool,

/// Enables the Pre-Vote algorithm described in raft thesis section
/// 9.6. This prevents disruption when a node that has been partitioned away
/// rejoins the cluster.
pub pre_vote: bool,

/// The range of election timeout. In some cases, we hope some nodes has less possibility
/// to become leader. This configuration ensures that the randomized election_timeout
/// will always be suit in [min_election_tick, max_election_tick).
/// If it is 0, then election_tick will be chosen.
pub min_election_tick: usize,

/// If it is 0, then 2 * election_tick will be chosen.
pub max_election_tick: usize,

/// Choose the linearizability mode or the lease mode to read data. If you don’t care about the read consistency and want a higher read performance, you can use the lease mode.
pub read_only_option: ReadOnlyOption,

/// Don't broadcast an empty raft entry to notify follower to commit an entry.
/// This may make follower wait a longer time to apply an entry. This configuration
/// May affect proposal forwarding and follower read.
pub skip_bcast_commit: bool,

/// A human-friendly tag used for logging.
pub tag: String,
}

impl Default for Config {
fn default() -> Self {
const HEARTBEAT_TICK: usize = 2;
Self {
id: 0,
peers: vec![],
learners: vec![],
election_tick: HEARTBEAT_TICK * 10,
heartbeat_tick: HEARTBEAT_TICK,
applied: 0,
max_size_per_msg: 0,
max_inflight_msgs: 256,
check_quorum: false,
pre_vote: false,
min_election_tick: 0,
max_election_tick: 0,
read_only_option: ReadOnlyOption::Safe,
skip_bcast_commit: false,
tag: "".into(),
}
}
}

impl Config {
/// Creates a new config.
pub fn new(id: u64) -> Self {
Self {
id,
tag: format!("{}", id),
..Self::default()
}
}

/// The minimum number of ticks before an election.
#[inline]
pub fn min_election_tick(&self) -> usize {
if self.min_election_tick == 0 {
self.election_tick
} else {
self.min_election_tick
}
}

/// The maximum number of ticks before an election.
#[inline]
pub fn max_election_tick(&self) -> usize {
if self.max_election_tick == 0 {
2 * self.election_tick
} else {
self.max_election_tick
}
}

/// Runs validations against the config.
pub fn validate(&self) -> Result<()> {
if self.id == INVALID_ID {
return Err(Error::ConfigInvalid("invalid node id".to_owned()));
}

if self.heartbeat_tick == 0 {
return Err(Error::ConfigInvalid(
"heartbeat tick must greater than 0".to_owned(),
));
}

if self.election_tick <= self.heartbeat_tick {
return Err(Error::ConfigInvalid(
"election tick must be greater than heartbeat tick".to_owned(),
));
}

let min_timeout = self.min_election_tick();
let max_timeout = self.max_election_tick();
if min_timeout < self.election_tick {
return Err(Error::ConfigInvalid(format!(
"min election tick {} must not be less than election_tick {}",
min_timeout, self.election_tick
)));
}

if min_timeout >= max_timeout {
return Err(Error::ConfigInvalid(format!(
"min election tick {} should be less than max election tick {}",
min_timeout, max_timeout
)));
}

if self.max_inflight_msgs == 0 {
return Err(Error::ConfigInvalid(
"max inflight messages must be greater than 0".to_owned(),
));
}

Ok(())
}
}
7 changes: 5 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ extern crate rand;
/// documented by field.
pub mod eraftpb;
mod errors;
mod config;
mod log_unstable;
mod progress;
mod raft;
Expand All @@ -243,8 +244,9 @@ pub use self::errors::{Error, Result, StorageError};
pub use self::log_unstable::Unstable;
pub use self::progress::{Inflights, Progress, ProgressSet, ProgressState};
pub use self::raft::{
quorum, vote_resp_msg_type, Config, Raft, SoftState, StateRole, INVALID_ID, INVALID_INDEX,
quorum, vote_resp_msg_type, Raft, SoftState, StateRole, INVALID_ID, INVALID_INDEX,
};
pub use self::config::Config;
pub use self::raft_log::{RaftLog, NO_LIMIT};
pub use self::raw_node::{is_empty_snap, Peer, RawNode, Ready, SnapshotStatus};
pub use self::read_only::{ReadOnlyOption, ReadState};
Expand All @@ -269,7 +271,8 @@ pub mod prelude {
Snapshot, SnapshotMetadata,
};

pub use raft::{Config, Raft};
pub use raft::Raft;
pub use config::Config;

pub use storage::{RaftState, Storage};

Expand Down
Loading

0 comments on commit 935840b

Please sign in to comment.