diff options
| author | tv <tv@krebsco.de> | 2026-11-03 07:55:09 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-03 07:55:09 +0100 |
| commit | 781dd223ec3260757299d79250d7448bc46f9814 (patch) | |
| tree | 6b5f38ede40e1ff4105fac641814c83f8136443a /src/api | |
| parent | 6aec18f10a965797a862360fde3dc8413e529d28 (diff) | |
dashboard: show reach set
Diffstat (limited to 'src/api')
| -rw-r--r-- | src/api/dashboard/dashboard.html | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/src/api/dashboard/dashboard.html b/src/api/dashboard/dashboard.html index b1aa821..94e3dfb 100644 --- a/src/api/dashboard/dashboard.html +++ b/src/api/dashboard/dashboard.html @@ -427,9 +427,14 @@ function focus(id) { // --- Peers --- function renderPeers() { const table = document.getElementById("peers"); + const headers = { reaches: "How many members besides this node it reaches (an active " + + "session with each), as it said; +: those of them this node doesn't reach itself (it " + + "is a way to them)" }; const rows = [el("tr", {}, ...["peer", "status", "seen", "via", "rtt", "clock", "neighbour", - "same epoch"] - .map(h => el("th", {}, h)))]; + "reaches", "same epoch"] + .map(h => el("th", { title: headers[h] || "" }, h)))]; + // Whom this node reaches, to tell those a peer reaches and it doesn't. + const ours = new Set(state.peers.localReaches || []); for (const [id, peer] of Object.entries(state.peers.peers)) { const destination = peer.destination; const path = destination && destination.paths && destination.paths[0]; @@ -450,6 +455,7 @@ function renderPeers() { ? "ahead of this node's by " + peer.clock.offsetMs + " ms, give or take " + peer.clock.withinMs + " ms" : "" }, peer.clock ? seconds(peer.clock.offsetMs) : ""), el("td", {}, peer.neighbour ? "yes" : ""), + reachesCell(peer.reaches, ours, id), el("td", {}, peer.sameEpoch === null || peer.sameEpoch === undefined ? "" : peer.sameEpoch ? "yes" : "no")); // On press: the table may be drawn anew (ages) before a click would complete. @@ -463,6 +469,21 @@ function renderPeers() { ? (rows[8].offsetTop + rows[8].offsetHeight) + "px" : ""; } +// Whom a peer reaches (`reaches`, as it said; null: it hasn't said in this session), as +// a count, and those of them this node doesn't reach (`ours`), marked: the peer is a way +// to them. Each by name in the tooltip. +function reachesCell(reaches, ours, id) { + if (!Array.isArray(reaches)) { + return el("td", { title: "hasn't said whom it reaches in this session" }, ""); + } + const others = reaches.filter(member => member !== state.node.id); + const only = others.filter(member => !ours.has(member) && member !== id); + const named = member => name(member) + (only.includes(member) ? " +" : ""); + return el("td", { title: others.length ? others.map(named).sort().join("\n") + : "reaches no other member" }, + String(others.length) + (only.length ? " (+" + only.length + ")" : "")); +} + // --- Figures: a tree, its open branches kept across renders --- const open = new Set(["stats", "peer", "links", "from", "to", "paths", "paths.destination"]); // As the page it was opened from had them (`handOver`). |
