diff options
| author | tv <tv@krebsco.de> | 2026-10-31 04:09:40 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-31 04:09:40 +0100 |
| commit | 47e00e5fde46b3460bf12097079e2510967c7010 (patch) | |
| tree | b0adc280cf36f45563fc30653ecb04021dc487b4 | |
| parent | 4be01038984c7c31433a20201de5638f23f4f2fb (diff) | |
add lastSyncSecsAgo and description to /peers
| -rw-r--r-- | docs/openapi.yaml | 13 | ||||
| -rw-r--r-- | src/api/dashboard/dashboard.html | 2 | ||||
| -rw-r--r-- | src/api/dashboard/mod.rs | 1 | ||||
| -rw-r--r-- | src/api/peers.rs | 11 |
4 files changed, 23 insertions, 4 deletions
diff --git a/docs/openapi.yaml b/docs/openapi.yaml index b04c98a..b7c632d 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -584,9 +584,10 @@ paths: `{"all": true}` when too many changed or the node lost count. When the node stops, an `offline` event ends the stream (a client reconnects once the node is back). Nothing changed, nothing is sent but keep-alive comments. - Ages (`…SecsAgo`, `secsAgo`, `uptimeSecs`, `dormantForSecs`, `observedSecs`, - `lastFromNeighbourSecs`, `oldestQuarantineSecs`) are as of the event: they - alone changing sends nothing, the client counts them on. Only with the + Ages (`…SecsAgo`, `secsAgo`, `uptimeSecs`, `dormantForSecs`, + `divergedForSecs`, `observedSecs`, `lastFromNeighbourSecs`, + `oldestQuarantineSecs`) are as of the event: they alone changing sends + nothing, the client counts them on. Only with the `dashboard` cargo feature. responses: '200': @@ -1337,6 +1338,12 @@ components: type: [integer, 'null'] dormantForSecs: type: [integer, 'null'] + lastSyncSecsAgo: + type: [integer, 'null'] + description: Since a sync message from it was applied (or the epoch changed). + divergedForSecs: + type: [integer, 'null'] + description: How long its heads have differed from ours with no sync message from it in between; null while they match. hasPendingDelivery: type: boolean epoch: diff --git a/src/api/dashboard/dashboard.html b/src/api/dashboard/dashboard.html index 0bbd9c5..091d7ee 100644 --- a/src/api/dashboard/dashboard.html +++ b/src/api/dashboard/dashboard.html @@ -163,7 +163,7 @@ let state = null; let stateAt = 0; // Fields that grow by themselves (`GROWING` and `is_age` in the node's dashboard). -const GROWING = new Set(["uptimeSecs", "dormantForSecs", "observedSecs", +const GROWING = new Set(["uptimeSecs", "dormantForSecs", "divergedForSecs", "observedSecs", "lastFromNeighbourSecs", "oldestQuarantineSecs"]); const isAge = key => key === "secsAgo" || key.endsWith("SecsAgo") || GROWING.has(key); const elapsed = () => Math.floor((Date.now() - stateAt) / 1000); diff --git a/src/api/dashboard/mod.rs b/src/api/dashboard/mod.rs index 86f349a..ad907ed 100644 --- a/src/api/dashboard/mod.rs +++ b/src/api/dashboard/mod.rs @@ -324,6 +324,7 @@ fn links_json(links: &[Link]) -> JsonValue { const GROWING: &[&str] = &[ "uptimeSecs", "dormantForSecs", + "divergedForSecs", "observedSecs", "lastFromNeighbourSecs", "oldestQuarantineSecs", diff --git a/src/api/peers.rs b/src/api/peers.rs index da714d0..2f93a43 100644 --- a/src/api/peers.rs +++ b/src/api/peers.rs @@ -61,6 +61,11 @@ pub(crate) struct PeerStatus { handshake_complete: bool, last_seen_secs_ago: Option<u64>, dormant_for_secs: Option<u64>, + /// Since a sync message from it was applied (or the epoch changed). + last_sync_secs_ago: Option<u64>, + /// How long its heads have differed from ours with no sync message from it in + /// between; absent while they match. + diverged_for_secs: Option<u64>, has_pending_delivery: bool, /// Epoch the peer last advertised; absent until it has sent a message. epoch: Option<EpochInfo>, @@ -166,6 +171,12 @@ pub(crate) async fn peer_list(state: &AppState) -> PeerListResponse { .last_seen .map(|t| now.saturating_duration_since(t).as_secs()), dormant_for_secs, + last_sync_secs_ago: ps + .last_sync_rx + .map(|t| now.saturating_duration_since(t).as_secs()), + diverged_for_secs: ps + .diverged_since + .map(|t| now.saturating_duration_since(t).as_secs()), has_pending_delivery: ps.sync.sending.is_some() || ps.sync.retry_at.is_some(), epoch: ps.epoch.map(EpochInfo::from), same_epoch: ps.epoch.map(|epoch| epoch == local_epoch), |
