Skip to content

Commit

Permalink
Move Raft node construction onto NodeState
Browse files Browse the repository at this point in the history
  • Loading branch information
erikgrinaker committed Jan 7, 2024
1 parent dbf66eb commit 88ea330
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 13 deletions.
16 changes: 15 additions & 1 deletion src/raft/node/follower.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use super::super::{Address, Event, Instruction, Message, RequestID, Response};
use super::super::{Address, Event, Instruction, Log, Message, RequestID, Response};
use super::{rand_election_timeout, Candidate, Node, NodeID, NodeState, Role, Term, Ticks};
use crate::error::{Error, Result};

use ::log::{debug, error, info, warn};
use std::collections::HashSet;
use tokio::sync::mpsc;

// A follower replicates state from a leader.
#[derive(Clone, Debug, PartialEq)]
Expand Down Expand Up @@ -37,6 +38,19 @@ impl Follower {
impl Role for Follower {}

impl NodeState<Follower> {
/// Creates a new node as a leaderless follower.
pub fn new(
id: NodeID,
peers: HashSet<NodeID>,
mut log: Log,
node_tx: mpsc::UnboundedSender<Message>,
state_tx: mpsc::UnboundedSender<Instruction>,
) -> Result<Self> {
let (term, voted_for) = log.get_term()?;
let role = Follower::new(None, voted_for);
Ok(NodeState { id, peers, term, log, node_tx, state_tx, role })
}

/// Asserts internal invariants.
fn assert(&mut self) -> Result<()> {
self.assert_node()?;
Expand Down
16 changes: 4 additions & 12 deletions src/raft/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ pub enum Node {
}

impl Node {
/// Creates a new Raft node, starting as a leaderless follower.
/// Creates a new Raft node, starting as a leaderless follower, or leader if
/// there are no peers.
pub async fn new(
id: NodeID,
peers: HashSet<NodeID>,
Expand All @@ -69,16 +70,7 @@ impl Node {
driver.apply_log(&mut *state, &mut log)?;
tokio::spawn(driver.drive(state));

let (term, voted_for) = log.get_term()?;
let node = NodeState {
id,
peers,
term,
log,
node_tx,
state_tx,
role: Follower::new(None, voted_for),
};
let node = NodeState::new(id, peers, log, node_tx, state_tx)?;
if node.peers.is_empty() {
// If there are no peers, become leader immediately.
return Ok(node.become_candidate()?.become_leader()?.into());
Expand Down Expand Up @@ -137,7 +129,7 @@ impl From<NodeState<Leader>> for Node {
pub trait Role: Clone + std::fmt::Debug + PartialEq {}

// A Raft node with role R
pub struct NodeState<R: Role> {
pub struct NodeState<R: Role = Follower> {
id: NodeID,
peers: HashSet<NodeID>,
term: Term,
Expand Down

0 comments on commit 88ea330

Please sign in to comment.