-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented skeleton code for master election
- Loading branch information
Showing
8 changed files
with
103 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
use std::net::SocketAddr; | ||
use std::collections::HashSet; | ||
|
||
use time::SteadyTime; | ||
|
||
mod node; | ||
mod settings; | ||
#[cfg(test)] mod test_mesh; | ||
#[cfg(test)] mod test_util; | ||
#[cfg(test)] mod test_split_brain; | ||
|
||
#[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
struct Id(String); | ||
|
||
|
||
enum Machine { | ||
Starting { leader_deadline: SteadyTime }, | ||
Electing { votes_for_me: HashSet<Id>, election_deadline: SteadyTime }, | ||
Voted { peer: Id, election_deadline: SteadyTime }, | ||
Leader { ping_time: SteadyTime }, | ||
Follower { leader_deadline: SteadyTime }, | ||
} | ||
|
||
struct Node { | ||
id: String, | ||
machine: Machine, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
use rand::{thread_rng, Rng}; | ||
use time::{SteadyTime, Duration}; | ||
|
||
use super::{Node, Machine}; | ||
use super::settings::start_timeout; | ||
|
||
|
||
impl Node { | ||
pub fn new<S:AsRef<str>>(id: S, now: SteadyTime) -> Node { | ||
Node { | ||
id: id.as_ref().to_string(), | ||
machine: Machine::Starting { | ||
leader_deadline: now + start_timeout(), | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
use time::Duration; | ||
use rand::{thread_rng, Rng}; | ||
|
||
/// The number of seconds just started worker waits it to be reached by | ||
/// leader. We usually don't care joining the cluster on start too much. | ||
/// Probably we want it to be bigger than: | ||
/// | ||
/// * TCP retransmision timeout (so that in flaky network we don't start too | ||
/// much elections, because they have big chance to fail) | ||
/// * Cantal's discovery time and time to propagate changes to the leader | ||
/// | ||
/// The random MESSAGE_TIMEOUT (constained by constants below) is added to | ||
/// this timeout. | ||
pub const START_TIMEOUT: i64 = 5000; | ||
|
||
/// On each leader's ping we start election timer of a random value in this | ||
/// range. If there is no heartbeat from leader during this timeout, we start | ||
/// election. Note that mio currently has only 200 ms precision timers. | ||
pub const MIN_MESSAGE_TIMEOUT: i64 = 1200; | ||
pub const MAX_MESSAGE_TIMEOUT: i64 = 3000; | ||
|
||
/// Leader ping interval | ||
/// | ||
/// Raft have it slightly less than MIN_MESSAGE_TIMEOUT. My intuition says that | ||
/// it's nicer to have 2x smaller, just like in almost every other heartbeating | ||
/// system. There is no good reason to wait so long for original Raft. I.e. | ||
/// it wants to reestablish consistency as fast as possible. But it may be | ||
/// nicer to keep lower elections for us. | ||
pub const HEARTBEAT_INTERVAL: u64 = 600; | ||
|
||
|
||
pub fn start_timeout() -> Duration { | ||
Duration::milliseconds(START_TIMEOUT) + election_ivl() | ||
} | ||
|
||
pub fn election_ivl() -> Duration { | ||
Duration::milliseconds( | ||
thread_rng().gen_range(MIN_MESSAGE_TIMEOUT, MAX_MESSAGE_TIMEOUT)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
//! Tests for the case network is full mesh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/// Tests of |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
//! Tests for partitioned network (split-brain) | ||
//! | ||
//! Note that unlike in most other leader election systems, we still elect a | ||
//! leader even in minority partition. Becase we don't care strong consistency. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
use time::{SteadyTime, Duration}; | ||
|
||
|
||
|
||
struct TimeScale { | ||
now: SteadyTime, | ||
} | ||
|
||
impl TimeScale { | ||
fn advance_ms(&mut self, ms: u64) { | ||
self.now += Duration::milliseconds(ms); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters