openraft 0.10.0-alpha.18

Advanced Raft consensus
Documentation
use crate::RaftState;
use crate::RaftTypeConfig;
use crate::ServerState;
use crate::engine::EngineConfig;

#[cfg(test)]
mod update_server_state_test;

/// Handle raft server-state related operations
pub(crate) struct ServerStateHandler<'st, C>
where C: RaftTypeConfig
{
    pub(crate) config: &'st EngineConfig<C>,
    pub(crate) state: &'st mut RaftState<C>,
}

impl<C> ServerStateHandler<'_, C>
where C: RaftTypeConfig
{
    /// Re-calculate the server-state if it changed, update the `server_state` field and dispatch
    /// commands to inform a runtime.
    pub(crate) fn update_server_state_if_changed(&mut self) {
        let server_state = self.state.calc_server_state(&self.config.id);

        tracing::debug!(
            "check server state: id: {}, prev: {:?}, curr: {:?}",
            self.config.id,
            self.state.server_state,
            server_state
        );

        if self.state.server_state == server_state {
            return;
        }

        let was_leader = self.state.server_state == ServerState::Leader;
        let is_leader = server_state == ServerState::Leader;

        if !was_leader && is_leader {
            tracing::info!("id={} becomes leader", &self.config.id);
        } else if was_leader && !is_leader {
            tracing::info!("id={} steps down from leader", &self.config.id);
        } else {
            // nothing to do
        }

        self.state.server_state = server_state;
    }
}