mirror of
https://github.com/MarekWo/mc-webui.git
synced 2026-08-06 16:53:21 +02:00
perf: resolve message metadata in one batched request
Every incoming echo triggers a sweep of the whole rendered message list, and refreshMessagesMeta() awaited one /api/messages/<id>/meta per message inside the loop. Messages that never gain a route (nothing heard them) never stop qualifying for the sweep, so the same ~180 messages were re-fetched every few seconds: 7,500 requests in nine minutes on a single tab, each opening its own SQLite connections. The single-threaded werkzeug server — the same one production runs — had no room left for anything else, so the UI hung on "Loading messages..." / "Connecting..." while the device was in fact connected. Add GET /api/messages/meta?ids=... resolving the whole sweep with a handful of queries, batching the row and echo lookups, and have the client collect ids first and fetch them in chunks. The per-message endpoint stays for forced single refreshes; both now share _build_message_meta() and the existing _build_channel_secrets / _get_row_pkt_payload helpers, so the payload is unchanged (verified byte-identical against the old response). Measured on the local container, 500 messages rendered / 181 needing meta: one 273 ms request in place of 181 sequential ones at ~82 ms each. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+27
-8
@@ -1218,9 +1218,17 @@ function appendMessageFromSocket(data) {
|
||||
markChannelAsRead(currentChannelIdx, msg.timestamp);
|
||||
}
|
||||
|
||||
// Cap on ids per /api/messages/meta request, to keep the query string short.
|
||||
const META_BATCH_SIZE = 200;
|
||||
|
||||
/**
|
||||
* Refresh metadata (SNR, hops, route, analyzer) for messages missing it.
|
||||
* Fetches /api/messages/<id>/meta for each incomplete message, updates DOM in-place.
|
||||
*
|
||||
* Every echo triggers a sweep of the whole rendered list, and messages that
|
||||
* never gain a route (no repeaters heard them) never stop qualifying — so this
|
||||
* must stay cheap. Ids are collected first and resolved with batched
|
||||
* /api/messages/meta calls; one request per message used to flood the
|
||||
* single-threaded server and hang the UI.
|
||||
*/
|
||||
async function refreshMessagesMeta(forceIds = []) {
|
||||
const container = document.getElementById('messagesList');
|
||||
@@ -1228,7 +1236,8 @@ async function refreshMessagesMeta(forceIds = []) {
|
||||
|
||||
const forced = new Set((forceIds || []).map(String));
|
||||
|
||||
// Find message wrappers that don't have full metadata yet
|
||||
// Collect message wrappers that don't have full metadata yet
|
||||
const pending = new Map(); // msgId -> wrapper
|
||||
const wrappers = container.querySelectorAll('.message-wrapper[data-msg-id]');
|
||||
for (const wrapper of wrappers) {
|
||||
const msgId = wrapper.dataset.msgId;
|
||||
@@ -1245,14 +1254,24 @@ async function refreshMessagesMeta(forceIds = []) {
|
||||
if (hasRoute && hasAnalyzer) continue;
|
||||
}
|
||||
|
||||
try {
|
||||
const resp = await fetch(`/api/messages/${msgId}/meta`);
|
||||
const meta = await resp.json();
|
||||
if (!meta.success) continue;
|
||||
pending.set(msgId, wrapper);
|
||||
}
|
||||
if (pending.size === 0) return;
|
||||
|
||||
updateMessageMetaDOM(wrapper, meta);
|
||||
const ids = Array.from(pending.keys());
|
||||
for (let i = 0; i < ids.length; i += META_BATCH_SIZE) {
|
||||
const chunk = ids.slice(i, i + META_BATCH_SIZE);
|
||||
try {
|
||||
const resp = await fetch(`/api/messages/meta?ids=${chunk.join(',')}`);
|
||||
const data = await resp.json();
|
||||
if (!data.success || !data.metas) continue;
|
||||
|
||||
for (const [msgId, meta] of Object.entries(data.metas)) {
|
||||
const wrapper = pending.get(msgId);
|
||||
if (wrapper && meta.success) updateMessageMetaDOM(wrapper, meta);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`Error fetching meta for msg #${msgId}:`, e);
|
||||
console.error('Error fetching message meta batch:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user