mirror of
https://github.com/MarekWo/mc-webui.git
synced 2026-08-04 16:03:07 +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:
@@ -834,6 +834,26 @@ class Database:
|
||||
).fetchone()
|
||||
return dict(row) if row else None
|
||||
|
||||
def get_channel_messages_by_ids(self, msg_ids: List[int]) -> Dict[int, Dict]:
|
||||
"""Batch-fetch channel messages by id with chunked IN queries.
|
||||
|
||||
Returns {msg_id: row dict}; ids with no row are simply absent.
|
||||
Chunked at 500 to stay under SQLite's host-parameter limit."""
|
||||
result: Dict[int, Dict] = {}
|
||||
if not msg_ids:
|
||||
return result
|
||||
with self._connect() as conn:
|
||||
for i in range(0, len(msg_ids), 500):
|
||||
chunk = msg_ids[i:i + 500]
|
||||
placeholders = ",".join("?" * len(chunk))
|
||||
rows = conn.execute(
|
||||
f"SELECT * FROM channel_messages WHERE id IN ({placeholders})",
|
||||
chunk
|
||||
).fetchall()
|
||||
for r in rows:
|
||||
result[r['id']] = dict(r)
|
||||
return result
|
||||
|
||||
def get_channel_messages(self, channel_idx: int = None, limit: int = 50,
|
||||
offset: int = 0, days: int = None) -> List[Dict]:
|
||||
with self._connect() as conn:
|
||||
|
||||
Reference in New Issue
Block a user