1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use crate::leader::voting::Voting;
use crate::leader::Leading;
use crate::quorum::Joint;
use crate::Instant;
use crate::NodeId;

/// The quorum set type used by `Leader`.
pub(crate) type LeaderQuorumSet<NID> = Joint<NID, Vec<NID>, Vec<Vec<NID>>>;

/// In openraft there are only two state for a server:
/// Leading(raft leader or raft candidate) and following(raft follower or raft learner):
///
/// - A leading state is able to vote(candidate in original raft) and is able to propose new log if
///   its vote is granted by quorum(leader in original raft).
///
///   In this way the leadership won't be lost when it sees a higher `vote` and needs upgrade its
/// `vote`.
///
/// - A following state just receives replication from a leader. A follower that is one of the
///   member will be able to become leader. A following state that is not a member is just a
///   learner.
#[derive(Clone, Debug)]
#[derive(PartialEq, Eq)]
// TODO(9): Make InternalServerState an Option, separate Leading(Proposer) role and
//          Following(Acceptor) role
pub(crate) enum InternalServerState<NID, I>
where
    NID: NodeId,
    I: Instant,
{
    /// Leader or candidate.
    ///
    /// `vote.committed==true` means it is a leader.
    Leading(Box<Leading<NID, LeaderQuorumSet<NID>, I>>),

    /// Follower or learner.
    ///
    /// Being a voter means it is a follower.
    Following,
}

impl<NID, I> Default for InternalServerState<NID, I>
where
    NID: NodeId,
    I: Instant,
{
    fn default() -> Self {
        Self::Following
    }
}

impl<NID, I> InternalServerState<NID, I>
where
    NID: NodeId,
    I: Instant,
{
    pub(crate) fn voting_mut(&mut self) -> Option<&mut Voting<NID, LeaderQuorumSet<NID>, I>> {
        match self {
            InternalServerState::Leading(l) => l.voting_mut(),
            InternalServerState::Following => None,
        }
    }

    pub(crate) fn leading(&self) -> Option<&Leading<NID, LeaderQuorumSet<NID>, I>> {
        match self {
            InternalServerState::Leading(l) => Some(l),
            InternalServerState::Following => None,
        }
    }

    pub(crate) fn leading_mut(&mut self) -> Option<&mut Leading<NID, LeaderQuorumSet<NID>, I>> {
        match self {
            InternalServerState::Leading(l) => Some(l),
            InternalServerState::Following => None,
        }
    }

    pub(crate) fn is_leading(&self) -> bool {
        match self {
            InternalServerState::Leading(_) => true,
            InternalServerState::Following => false,
        }
    }

    #[allow(dead_code)]
    pub(crate) fn is_following(&self) -> bool {
        !self.is_leading()
    }
}