diff options
Diffstat (limited to 'src/api/peers.rs')
| -rw-r--r-- | src/api/peers.rs | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/src/api/peers.rs b/src/api/peers.rs index b2658a5..b12e3bf 100644 --- a/src/api/peers.rs +++ b/src/api/peers.rs @@ -15,6 +15,7 @@ use utoipa::ToSchema; use super::store_status; use crate::peer::forgotten_path; +use crate::replica::Epoch; use crate::state::{unix_millis, AppState, HelloState, Liveness, PeerMembership, PeerState}; use crate::store; @@ -27,6 +28,23 @@ pub(crate) enum PeerLivenessStatus { #[derive(Debug, Serialize, ToSchema)] #[serde(rename_all = "camelCase")] +pub(crate) struct EpochInfo { + generation: u64, + /// Hex-encoded snapshot hash; all zeros for the genesis epoch. + id: String, +} + +impl From<Epoch> for EpochInfo { + fn from(epoch: Epoch) -> Self { + Self { + generation: epoch.generation, + id: epoch.id_hex(), + } + } +} + +#[derive(Debug, Serialize, ToSchema)] +#[serde(rename_all = "camelCase")] pub(crate) struct PeerStatus { public_key: String, validated_cluster: Option<String>, @@ -35,11 +53,16 @@ pub(crate) struct PeerStatus { last_seen_secs_ago: Option<u64>, dormant_for_secs: Option<u64>, has_pending_delivery: bool, + /// Epoch the peer last advertised; absent until it has sent a message. + epoch: Option<EpochInfo>, + /// Whether that epoch equals ours, i.e. whether we sync with this peer. + same_epoch: Option<bool>, } #[derive(Debug, Serialize, ToSchema)] #[serde(rename_all = "camelCase")] pub(crate) struct PeerListResponse { + local_epoch: EpochInfo, peers: Vec<PeerStatus>, } @@ -73,6 +96,7 @@ pub(crate) async fn list_peers( .collect(); let now = Instant::now(); + let local_epoch = state.local_epoch(); let mut peers = Vec::with_capacity(snapshot.len()); for (public_key, peer_state_mutex) in snapshot { @@ -99,11 +123,16 @@ pub(crate) async fn list_peers( .map(|t| now.saturating_duration_since(t).as_secs()), dormant_for_secs, has_pending_delivery: ps.pending_outbound_sync.is_some(), + epoch: ps.epoch.map(EpochInfo::from), + same_epoch: ps.epoch.map(|epoch| epoch == local_epoch), }); } peers.sort_by(|a, b| a.public_key.cmp(&b.public_key)); - Ok(Json(PeerListResponse { peers })) + Ok(Json(PeerListResponse { + local_epoch: local_epoch.into(), + peers, + })) } #[utoipa::path( |
