aboutsummaryrefslogtreecommitdiffstats
path: root/src/api/dashboard
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-09 00:22:05 +0000
committertv <tv@krebsco.de>2026-11-09 00:22:05 +0000
commite2a57d301529300d9236a468f190cc046eba1cd7 (patch)
tree5bdd504e3fcf7ca10963515d24cd7b4543948d30 /src/api/dashboard
parenta20aedfbe27082a263e767aeb491ccbdd2c9d222 (diff)
dashboard: the console in the order messages went
The console appended messages as their streams brought them, a subscribed node's later than this node's by its path, each line with its node's own clock's time: lines of one moment came apart, and their times read out of order. Each message is now listed by when its node logged it, on this node's clock, as the map runs them (`aheadOf`): one a slower stream brought late goes in among those of its moment. The time shown is on this node's clock; a subscribed node's own clock's time is in its tooltip.
Diffstat (limited to 'src/api/dashboard')
-rw-r--r--src/api/dashboard/dashboard.html24
1 files changed, 20 insertions, 4 deletions
diff --git a/src/api/dashboard/dashboard.html b/src/api/dashboard/dashboard.html
index b53c7b1..1d95db1 100644
--- a/src/api/dashboard/dashboard.html
+++ b/src/api/dashboard/dashboard.html
@@ -3526,7 +3526,7 @@ function consoleLine(message) {
// A subscribed node's (`remoteMessagesArrived`): its receiver, and whom from.
const between = message.node ? name(message.to) + " ← " + name(message.from) + " "
: WAYS[message.way] + " " + name(message.peer) + " ";
- const line = el("div", { "data-seq": String(message.seq),
+ const line = el("div", { "data-seq": String(message.seq), "data-t": String(message.t || 0),
"data-related": message.related || "",
"data-peer": message.node ? "" : message.peer,
"data-from": message.from || "", "data-to": message.to || "",
@@ -3535,7 +3535,10 @@ function consoleLine(message) {
peerClasses(message),
title: message.way === "refused" ? "refused: the transport wouldn't send it"
: message.node ? "logged by " + name(message.node) + ", subscribed to" : "" },
- el("span", { class: "when" }, clockTime(new Date(message.at)) + " "),
+ // On this node's clock, as they are ordered; by its node's own in the tooltip.
+ el("span", { class: "when", title: message.node && Math.round(message.t || message.at) !==
+ message.at ? "by " + name(message.node) + "'s clock " + clockTime(new Date(message.at)) : "" },
+ clockTime(new Date(Math.round(message.t || message.at))) + " "),
between,
el("span", { style: "color: " + kindColour(message.counted) }, message.type),
" " + size(message.bytes));
@@ -3558,14 +3561,27 @@ function showMessage(message) {
markRelated(message !== null ? message.related : null);
render();
}
+// In the order they went, as the map runs them (`aheadOf`): each placed by when its node
+// logged it, on this node's clock (`t`), among those that came before it, however late
+// its node's stream brought it.
function messagesArrived(messages) {
- consoleMessages.push(...messages);
+ for (const message of messages) {
+ message.t = message.at - (state ? aheadOf(message.node || state.node.id) : 0);
+ let i = consoleMessages.length;
+ while (i > 0 && consoleMessages[i - 1].t > message.t) i--;
+ consoleMessages.splice(i, 0, message);
+ }
consoleMessages.splice(0, Math.max(0, consoleMessages.length - CONSOLE_LINES));
if (hidden(document.getElementById("console-box"))) return;
const log = document.getElementById("console");
const scroll = document.getElementById("console-scroll");
const following = scroll.scrollTop + scroll.clientHeight >= scroll.scrollHeight - 4;
- log.append(...messages.slice(-CONSOLE_LINES).map(consoleLine));
+ for (const message of messages.slice(-CONSOLE_LINES)) {
+ let before = null;
+ for (let line = log.lastElementChild; line && Number(line.dataset.t) > message.t;
+ line = line.previousElementSibling) before = line;
+ log.insertBefore(consoleLine(message), before);
+ }
while (log.childElementCount > CONSOLE_LINES) log.firstElementChild.remove();
filterConsole();
if (following) scroll.scrollTop = scroll.scrollHeight;