Skip to content

Commit 065c37d

Browse files
authored
Add more convenient lite-weight interfaces (#227)
This PR introduces two simple and lite weight interfaces: - ping to trigger heartbeats without ticking, - status_ref to borrow the progress set instead of cloning.
1 parent 64571f0 commit 065c37d

4 files changed

Lines changed: 57 additions & 4 deletions

File tree

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ pub use self::raft::{
305305
pub use self::raft_log::{RaftLog, NO_LIMIT};
306306
pub use self::raw_node::{is_empty_snap, Peer, RawNode, Ready, SnapshotStatus};
307307
pub use self::read_only::{ReadOnlyOption, ReadState};
308-
pub use self::status::Status;
308+
pub use self::status::{Status, StatusRef};
309309
pub use self::storage::{RaftState, Storage};
310310

311311
pub mod prelude {
@@ -335,7 +335,7 @@ pub mod prelude {
335335

336336
pub use progress::Progress;
337337

338-
pub use status::Status;
338+
pub use status::{Status, StatusRef};
339339

340340
pub use read_only::{ReadOnlyOption, ReadState};
341341
}

src/raft.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,13 @@ impl<T: Storage> Raft<T> {
566566
self.set_prs(prs);
567567
}
568568

569+
/// Broadcasts heartbeats to all the followers if it's leader.
570+
pub fn ping(&mut self) {
571+
if self.state == StateRole::Leader {
572+
self.bcast_heartbeat();
573+
}
574+
}
575+
569576
/// Sends RPC, without entries to all the peers.
570577
pub fn bcast_heartbeat(&mut self) {
571578
let ctx = self.read_only.last_pending_request_ctx();

src/raw_node.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ use protobuf::{self, RepeatedField};
4141
use super::config::Config;
4242
use super::errors::{Error, Result};
4343
use super::read_only::ReadState;
44-
use super::Status;
4544
use super::Storage;
4645
use super::{Raft, SoftState, INVALID_ID};
46+
use super::{Status, StatusRef};
4747

4848
/// Represents a Peer node in the cluster.
4949
#[derive(Debug, Default)]
@@ -286,6 +286,13 @@ impl<T: Storage> RawNode<T> {
286286
self.raft.step(m)
287287
}
288288

289+
/// Broadcast heartbeats to all the followers.
290+
///
291+
/// If it's not leader, nothing will happen.
292+
pub fn ping(&mut self) {
293+
self.raft.ping()
294+
}
295+
289296
/// ProposeConfChange proposes a config change.
290297
#[cfg_attr(feature = "cargo-clippy", allow(clippy::needless_pass_by_value))]
291298
pub fn propose_conf_change(&mut self, context: Vec<u8>, cc: ConfChange) -> Result<()> {
@@ -423,6 +430,13 @@ impl<T: Storage> RawNode<T> {
423430
Status::new(&self.raft)
424431
}
425432

433+
/// Returns the current status of the given group.
434+
///
435+
/// It's borrows the internal progress set instead of copying.
436+
pub fn status_ref(&self) -> StatusRef {
437+
StatusRef::new(&self.raft)
438+
}
439+
426440
/// ReportUnreachable reports the given node is not reachable for the last send.
427441
pub fn report_unreachable(&mut self, id: u64) {
428442
let mut m = Message::new();

src/status.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
use eraftpb::HardState;
2929
use fxhash::FxHashMap;
3030

31-
use progress::Progress;
31+
use progress::{Progress, ProgressSet};
3232
use raft::{Raft, SoftState, StateRole};
3333
use storage::Storage;
3434

@@ -66,3 +66,35 @@ impl Status {
6666
s
6767
}
6868
}
69+
70+
/// Represents the current status of the raft
71+
#[derive(Default)]
72+
pub struct StatusRef<'a> {
73+
/// The ID of the current node.
74+
pub id: u64,
75+
/// The hardstate of the raft, representing voted state.
76+
pub hs: HardState,
77+
/// The softstate of the raft, representing proposed state.
78+
pub ss: SoftState,
79+
/// The index of the last entry to have been applied.
80+
pub applied: u64,
81+
/// The progress towards catching up and applying logs.
82+
pub progress: Option<&'a ProgressSet>,
83+
}
84+
85+
impl<'a> StatusRef<'a> {
86+
/// Gets the current raft status.
87+
pub fn new<T: Storage>(raft: &'a Raft<T>) -> StatusRef<'a> {
88+
let mut s = StatusRef {
89+
id: raft.id,
90+
..Default::default()
91+
};
92+
s.hs = raft.hard_state();
93+
s.ss = raft.soft_state();
94+
s.applied = raft.raft_log.get_applied();
95+
if s.ss.raft_state == StateRole::Leader {
96+
s.progress = Some(raft.prs());
97+
}
98+
s
99+
}
100+
}

0 commit comments

Comments
 (0)