Skip to content

Commit c07aa4a

Browse files
committed
raft: rename RoleNode to Node and add Role trait
1 parent 2faf4e4 commit c07aa4a

File tree

4 files changed

+37
-37
lines changed

4 files changed

+37
-37
lines changed

src/raft/node/candidate.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::super::{Address, Event, Message};
22
use super::{
3-
rand_election_timeout, BoxedNode, DynNode, Follower, Leader, NodeID, RoleNode, Term, Ticks,
3+
rand_election_timeout, BoxedNode, DynNode, Follower, Leader, Node, NodeID, Role, Term, Ticks,
44
};
55
use crate::error::{Error, Result};
66

@@ -29,7 +29,9 @@ impl Candidate {
2929
}
3030
}
3131

32-
impl RoleNode<Candidate> {
32+
impl Role for Candidate {}
33+
34+
impl Node<Candidate> {
3335
/// Asserts internal invariants.
3436
fn assert(&mut self) -> Result<()> {
3537
self.assert_node()?;
@@ -49,7 +51,7 @@ impl RoleNode<Candidate> {
4951
/// Transforms the node into a follower. We either lost the election
5052
/// and follow the winner, or we discovered a new term in which case
5153
/// we step into it as a leaderless follower.
52-
fn become_follower(mut self, term: Term, leader: Option<NodeID>) -> Result<RoleNode<Follower>> {
54+
fn become_follower(mut self, term: Term, leader: Option<NodeID>) -> Result<Node<Follower>> {
5355
assert!(term >= self.term, "Term regression {} -> {}", self.term, term);
5456

5557
if let Some(leader) = leader {
@@ -70,7 +72,7 @@ impl RoleNode<Candidate> {
7072
}
7173

7274
/// Transition to leader role.
73-
fn become_leader(self) -> Result<RoleNode<Leader>> {
75+
fn become_leader(self) -> Result<Node<Leader>> {
7476
info!("Won election for term {}, becoming leader", self.term);
7577
let peers = self.peers.clone();
7678
let (last_index, _) = self.log.get_last_index();
@@ -99,7 +101,7 @@ impl RoleNode<Candidate> {
99101
}
100102
}
101103

102-
impl DynNode for RoleNode<Candidate> {
104+
impl DynNode for Node<Candidate> {
103105
fn id(&self) -> NodeID {
104106
self.id
105107
}

src/raft/node/follower.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use super::super::{Address, Event, Instruction, Message, RequestID, Response};
2-
use super::{rand_election_timeout, BoxedNode, Candidate, DynNode, NodeID, RoleNode, Term, Ticks};
2+
use super::{
3+
rand_election_timeout, BoxedNode, Candidate, DynNode, Node, NodeID, Role, Term, Ticks,
4+
};
35
use crate::error::{Error, Result};
46

57
use ::log::{debug, error, info, warn};
@@ -34,7 +36,9 @@ impl Follower {
3436
}
3537
}
3638

37-
impl RoleNode<Follower> {
39+
impl Role for Follower {}
40+
41+
impl Node<Follower> {
3842
/// Asserts internal invariants.
3943
fn assert(&mut self) -> Result<()> {
4044
self.assert_node()?;
@@ -59,7 +63,7 @@ impl RoleNode<Follower> {
5963

6064
/// Transforms the node into a candidate, by campaigning for leadership in a
6165
/// new term.
62-
fn become_candidate(mut self) -> Result<RoleNode<Candidate>> {
66+
fn become_candidate(mut self) -> Result<Node<Candidate>> {
6367
// Abort any forwarded requests. These must be retried with new leader.
6468
self.abort_forwarded()?;
6569

@@ -70,7 +74,7 @@ impl RoleNode<Follower> {
7074

7175
/// Transforms the node into a follower, either a leaderless follower in a
7276
/// new term or following a leader in the current term.
73-
fn become_follower(mut self, leader: Option<NodeID>, term: Term) -> Result<RoleNode<Follower>> {
77+
fn become_follower(mut self, leader: Option<NodeID>, term: Term) -> Result<Node<Follower>> {
7478
assert!(term >= self.term, "Term regression {} -> {}", self.term, term);
7579

7680
// Abort any forwarded requests. These must be retried with new leader.
@@ -114,7 +118,7 @@ impl RoleNode<Follower> {
114118
}
115119
}
116120

117-
impl DynNode for RoleNode<Follower> {
121+
impl DynNode for Node<Follower> {
118122
fn id(&self) -> NodeID {
119123
self.id
120124
}

src/raft/node/leader.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::super::{Address, Event, Index, Instruction, Message, Request, Response, Status};
2-
use super::{BoxedNode, DynNode, Follower, NodeID, RoleNode, Term, Ticks, HEARTBEAT_INTERVAL};
2+
use super::{BoxedNode, DynNode, Follower, Node, NodeID, Role, Term, Ticks, HEARTBEAT_INTERVAL};
33
use crate::error::Result;
44

55
use ::log::{debug, info};
@@ -32,7 +32,9 @@ impl Leader {
3232
}
3333
}
3434

35-
impl RoleNode<Leader> {
35+
impl Role for Leader {}
36+
37+
impl Node<Leader> {
3638
/// Asserts internal invariants.
3739
fn assert(&mut self) -> Result<()> {
3840
self.assert_node()?;
@@ -45,7 +47,7 @@ impl RoleNode<Leader> {
4547

4648
/// Transforms the leader into a follower. This can only happen if we find a
4749
/// new term, so we become a leaderless follower.
48-
fn become_follower(mut self, term: Term) -> Result<RoleNode<Follower>> {
50+
fn become_follower(mut self, term: Term) -> Result<Node<Follower>> {
4951
assert!(term >= self.term, "Term regression {} -> {}", self.term, term);
5052
assert!(term > self.term, "Can only become follower in later term");
5153

@@ -144,7 +146,7 @@ impl RoleNode<Leader> {
144146
}
145147
}
146148

147-
impl DynNode for RoleNode<Leader> {
149+
impl DynNode for Node<Leader> {
148150
fn id(&self) -> NodeID {
149151
self.id
150152
}

src/raft/node/mod.rs

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub struct Status {
5252
/// a trait object, which hides the internal node state. This is more
5353
/// ergonomic, for two reasons:
5454
///
55-
/// - It allows use as "node = node.step()?" across typestate transitions (e.g.
55+
/// - It allows use as "node = node.step()?" across typestate transitions (e.g.
5656
/// candidate to leader),
5757
///
5858
/// - It hides generic type parameters (e.g. E: Engine), so they do not
@@ -91,7 +91,7 @@ pub async fn new_node(
9191

9292
let (term, voted_for) = log.get_term()?;
9393
let mut node =
94-
RoleNode { id, peers, term, log, node_tx, state_tx, role: Follower::new(None, voted_for) };
94+
Node { id, peers, term, log, node_tx, state_tx, role: Follower::new(None, voted_for) };
9595
if node.peers.is_empty() {
9696
info!("No peers specified, starting as leader");
9797
// If we didn't vote for ourself in the persisted term, bump the
@@ -107,8 +107,11 @@ pub async fn new_node(
107107
}
108108
}
109109

110-
// A Raft node with role R
111-
pub struct RoleNode<R> {
110+
/// A Raft role -- either leader, follower, or candidate.
111+
trait Role {}
112+
113+
/// A Raft node with role R.
114+
struct Node<R: Role> {
112115
id: NodeID,
113116
peers: HashSet<NodeID>,
114117
term: Term,
@@ -118,10 +121,10 @@ pub struct RoleNode<R> {
118121
role: R,
119122
}
120123

121-
impl<R> RoleNode<R> {
124+
impl<R: Role> Node<R> {
122125
/// Transforms the node into another role.
123-
fn become_role<T>(self, role: T) -> RoleNode<T> {
124-
RoleNode {
126+
fn become_role<T: Role>(self, role: T) -> Node<T> {
127+
Node {
125128
id: self.id,
126129
peers: self.peers,
127130
term: self.term,
@@ -137,7 +140,7 @@ impl<R> RoleNode<R> {
137140
(self.peers.len() as u64 + 1) / 2 + 1
138141
}
139142

140-
/// Sends an event
143+
/// Sends an event.
141144
fn send(&self, to: Address, event: Event) -> Result<()> {
142145
let msg = Message { term: self.term, from: Address::Node(self.id), to, event };
143146
debug!("Sending {:?}", msg);
@@ -207,17 +210,17 @@ mod tests {
207210
assert_eq!(msgs, actual);
208211
}
209212

210-
fn setup_rolenode() -> Result<(RoleNode<()>, mpsc::UnboundedReceiver<Message>)> {
213+
fn setup_rolenode() -> Result<(Node<Follower>, mpsc::UnboundedReceiver<Message>)> {
211214
setup_rolenode_peers(vec![2, 3])
212215
}
213216

214217
fn setup_rolenode_peers(
215218
peers: Vec<NodeID>,
216-
) -> Result<(RoleNode<()>, mpsc::UnboundedReceiver<Message>)> {
219+
) -> Result<(Node<Follower>, mpsc::UnboundedReceiver<Message>)> {
217220
let (node_tx, node_rx) = mpsc::unbounded_channel();
218221
let (state_tx, _) = mpsc::unbounded_channel();
219-
let node = RoleNode {
220-
role: (),
222+
let node = Node {
223+
role: Follower::new(None, None),
221224
id: 1,
222225
peers: HashSet::from_iter(peers),
223226
term: 1,
@@ -279,17 +282,6 @@ mod tests {
279282
new_node(1, HashSet::from([2, 3]), log, state.clone(), node_tx).await.unwrap();
280283
}
281284

282-
#[test]
283-
fn become_role() -> Result<()> {
284-
let (node, _) = setup_rolenode()?;
285-
let new = node.become_role("role");
286-
assert_eq!(new.id, 1);
287-
assert_eq!(new.term, 1);
288-
assert_eq!(new.peers, HashSet::from([2, 3]));
289-
assert_eq!(new.role, "role");
290-
Ok(())
291-
}
292-
293285
#[test]
294286
fn quorum() -> Result<()> {
295287
let quorums = vec![(1, 1), (2, 2), (3, 2), (4, 3), (5, 3), (6, 4), (7, 4), (8, 5)];

0 commit comments

Comments
 (0)