Skip to content

Commit

Permalink
Add more convenient lite-weight interfaces (#227)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
BusyJay authored Apr 29, 2019
1 parent 64571f0 commit 065c37d
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ pub use self::raft::{
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 mod prelude {
Expand Down Expand Up @@ -335,7 +335,7 @@ pub mod prelude {

pub use progress::Progress;

pub use status::Status;
pub use status::{Status, StatusRef};

pub use read_only::{ReadOnlyOption, ReadState};
}
Expand Down
7 changes: 7 additions & 0 deletions src/raft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,13 @@ impl<T: Storage> Raft<T> {
self.set_prs(prs);
}

/// Broadcasts heartbeats to all the followers if it's leader.
pub fn ping(&mut self) {
if self.state == StateRole::Leader {
self.bcast_heartbeat();
}
}

/// Sends RPC, without entries to all the peers.
pub fn bcast_heartbeat(&mut self) {
let ctx = self.read_only.last_pending_request_ctx();
Expand Down
16 changes: 15 additions & 1 deletion src/raw_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ use protobuf::{self, RepeatedField};
use super::config::Config;
use super::errors::{Error, Result};
use super::read_only::ReadState;
use super::Status;
use super::Storage;
use super::{Raft, SoftState, INVALID_ID};
use super::{Status, StatusRef};

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

/// Broadcast heartbeats to all the followers.
///
/// If it's not leader, nothing will happen.
pub fn ping(&mut self) {
self.raft.ping()
}

/// ProposeConfChange proposes a config change.
#[cfg_attr(feature = "cargo-clippy", allow(clippy::needless_pass_by_value))]
pub fn propose_conf_change(&mut self, context: Vec<u8>, cc: ConfChange) -> Result<()> {
Expand Down Expand Up @@ -423,6 +430,13 @@ impl<T: Storage> RawNode<T> {
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::new();
Expand Down
34 changes: 33 additions & 1 deletion src/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
use eraftpb::HardState;
use fxhash::FxHashMap;

use progress::Progress;
use progress::{Progress, ProgressSet};
use raft::{Raft, SoftState, StateRole};
use storage::Storage;

Expand Down Expand Up @@ -66,3 +66,35 @@ impl Status {
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<T: Storage>(raft: &'a Raft<T>) -> 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
}
}

0 comments on commit 065c37d

Please sign in to comment.