Skip to content

Commit

Permalink
WIP: election details
Browse files Browse the repository at this point in the history
  • Loading branch information
tailhook committed Oct 27, 2015
1 parent 2187295 commit 210b365
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 11 deletions.
4 changes: 3 additions & 1 deletion src/elect/action.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use time::SteadyTime;

use super::{Id};


#[derive(PartialEq, Eq, Debug)]
pub enum Action {
PingAll,
Vote,
ConfirmVote,
ConfirmVote(Id),
PingNew,
}

Expand Down
8 changes: 3 additions & 5 deletions src/elect/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ mod external;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
struct Id(String);


type Capsule = (u64, Message);

#[derive(Clone, Debug)]
enum Machine {
Expand All @@ -34,10 +34,8 @@ enum Message {
Ping,
/// Pong message from follower to leader, confirm that node is a leader
Pong,
/// New node or node recover is detected by cantal
NodeAdded,
/// Node death is detected by cantal
NodeRemoved,
/// Vote for some node
Vote(Id),
}

#[derive(Clone, Debug)]
Expand Down
39 changes: 35 additions & 4 deletions src/elect/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::collections::HashSet;
use rand::{thread_rng, Rng};
use time::{SteadyTime, Duration};

use super::{Id, Node, Machine, Message, ExternalData};
use super::settings::{start_timeout, HEARTBEAT_INTERVAL};
use super::{Id, Node, Machine, Message, ExternalData, Capsule};
use super::settings::{start_timeout, election_ivl, HEARTBEAT_INTERVAL};
use super::action::{Action, ActionList};


Expand Down Expand Up @@ -53,7 +53,38 @@ impl Node {
},
action)
}
pub fn message(self, msg: Message) -> (Node, ActionList) {
unimplemented!();
pub fn message(self, msg: Capsule, now: SteadyTime) -> (Node, ActionList) {
use super::Machine::*;
use super::Message::*;
let (num, data) = msg;

let (machine, action) = match (self.machine, data) {
(Starting { .. }, Ping) => {
let dline = now + election_ivl();
(Follower { leader_deadline: dline }, Action::wait(dline))
}
(Starting { leader_deadline: dline }, Pong) => {
// This probably means this node was a leader. But there is
// no guarantee that no leader has been already elected, so
// we just continue work
(Starting { leader_deadline: dline }, Action::wait(dline))
}
(Starting { leader_deadline }, Vote(id)) => {
let dline = now + election_ivl();
(Voted { peer: id.clone(), election_deadline: dline},
Action::ConfirmVote(id).and_wait(leader_deadline))
}
(Electing { .. }, _) => unimplemented!(),
(Voted { .. }, _) => unimplemented!(),
(Leader { .. }, _) => unimplemented!(),
(Follower { .. }, _) => unimplemented!(),
};
return (
Node {
machine: machine,
id: self.id,
ext: self.ext,
},
action)
}
}
20 changes: 19 additions & 1 deletion src/elect/test_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
use time::SteadyTime;

use super::{Node, Machine};
use super::{Node, Machine, Message};
use super::action::Action;
use super::test_util::Environ;

Expand Down Expand Up @@ -41,3 +41,21 @@ fn test_start_vote() {
assert!(matches!(node.machine, Machine::Electing { .. }));
assert!(act.action == Some(Action::Vote));
}

#[test]
fn test_vote_approved() {
let mut env = Environ::new();
let mut node = Node::new("one", env.now());
let id = node.id.clone();
assert!(matches!(node.machine, Machine::Starting { .. }));

env.add_another_for(&mut node);
env.sleep(10000); // Large timeout, should start_election
let (node, act) = node.time_passed(env.now());
assert!(matches!(node.machine, Machine::Electing { .. }));
assert!(act.action == Some(Action::Vote));

let (node, act) = node.message(Message::Vote(id.clone()), env.now());
assert!(matches!(node.machine, Machine::Leader { .. }));
assert!(act.action == Some(Action::PingAll));
}

0 comments on commit 210b365

Please sign in to comment.