diff --git a/src/lib.rs b/src/lib.rs index 30ebd493b..668ca54c8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -406,7 +406,7 @@ pub use self::raft::{vote_resp_msg_type, Raft, SoftState, StateRole, INVALID_ID, pub use self::raft_log::{RaftLog, NO_LIMIT}; pub use self::raw_node::{is_empty_snap, Peer, RawNode, Ready, SnapshotStatus}; pub use self::read_only::{ReadOnlyOption, ReadState}; -pub use self::status::Status; +pub use self::status::{Status, StatusRef}; pub use self::storage::{RaftState, Storage}; pub use raft_proto::eraftpb; use slog::{Drain, Logger}; @@ -435,7 +435,7 @@ pub mod prelude { pub use crate::progress::Progress; - pub use crate::status::Status; + pub use crate::status::{Status, StatusRef}; pub use crate::read_only::{ReadOnlyOption, ReadState}; } diff --git a/src/raft.rs b/src/raft.rs index dac0c7974..8f70d946b 100644 --- a/src/raft.rs +++ b/src/raft.rs @@ -681,9 +681,7 @@ impl Raft { self.set_prs(prs); } - /// Broadcast heartbeats to all the followers. - /// - /// If it's not leader, nothing will happen. + /// Broadcasts heartbeats to all the followers if it's leader. pub fn ping(&mut self) { if self.state == StateRole::Leader { self.bcast_heartbeat(); diff --git a/src/raw_node.rs b/src/raw_node.rs index e2f7a4c4f..28c2b0d97 100644 --- a/src/raw_node.rs +++ b/src/raw_node.rs @@ -42,7 +42,7 @@ use crate::eraftpb::{ }; use crate::errors::{Error, Result}; use crate::read_only::ReadState; -use crate::{Raft, SoftState, Status, Storage, INVALID_ID}; +use crate::{Raft, SoftState, Status, StatusRef, Storage, INVALID_ID}; use slog::Logger; /// Represents a Peer node in the cluster. @@ -456,6 +456,13 @@ impl RawNode { Status::new(&self.raft) } + /// Returns the current status of the given group. + /// + /// It's borrows the internal progress set instead of copying. + pub fn status_ref(&self) -> StatusRef { + StatusRef::new(&self.raft) + } + /// ReportUnreachable reports the given node is not reachable for the last send. pub fn report_unreachable(&mut self, id: u64) { let mut m = Message::default(); diff --git a/src/status.rs b/src/status.rs index 776810b52..64091c517 100644 --- a/src/status.rs +++ b/src/status.rs @@ -62,3 +62,35 @@ impl<'a> Status<'a> { s } } + +/// Represents the current status of the raft +#[derive(Default)] +pub struct StatusRef<'a> { + /// The ID of the current node. + pub id: u64, + /// The hardstate of the raft, representing voted state. + pub hs: HardState, + /// The softstate of the raft, representing proposed state. + pub ss: SoftState, + /// The index of the last entry to have been applied. + pub applied: u64, + /// The progress towards catching up and applying logs. + pub progress: Option<&'a ProgressSet>, +} + +impl<'a> StatusRef<'a> { + /// Gets the current raft status. + pub fn new(raft: &'a Raft) -> StatusRef<'a> { + let mut s = StatusRef { + id: raft.id, + ..Default::default() + }; + s.hs = raft.hard_state(); + s.ss = raft.soft_state(); + s.applied = raft.raft_log.get_applied(); + if s.ss.raft_state == StateRole::Leader { + s.progress = Some(raft.prs()); + } + s + } +}