dashboard: pass kinds= on the 4 unfiltered /api/dashboard/stream subscribers
Part 1 of the dashboard-event-stream-split epic: the server-side kinds= allow-list already exists and flow.js already uses it (hive-c0re/src/dashboard/state_snapshot.rs). tabs.js, builds.js, core.js, and logs.js were the remaining 4 subscribers still taking every wire kind unfiltered — pure subscription discipline, no new endpoint needed, per the investigation on the tracking issue. Each kinds= list is read directly off that page's own existing MUTATION_HANDLERS/SSE_HANDLERS dispatch table (tabs.js also needs sent, checked separately for the operator inbox) — a kind not in a page's table was already a silent no-op today, so this only removes wire/parse/dispatch-lookup cost for kinds a page never acted on, zero behavior change. Note for reviewers: the SharedWorker (stream-worker.js) multiplexes by exact URL string, so pages that used to share one unfiltered upstream connection when open simultaneously (e.g. dashboard.html + builds.html in two tabs) will now each hold their own filtered connection instead, since their kinds= differ. Each connection is still a single cheap SSE stream carrying only what that page acts on — net win over the shared-but-bloated connection this replaces.
This commit is contained in:
parent
a3a0b34668
commit
f60e8a8470
4 changed files with 41 additions and 9 deletions
|
|
@ -794,7 +794,14 @@ async function init() {
|
||||||
|
|
||||||
await refreshState();
|
await refreshState();
|
||||||
|
|
||||||
const es = openStream('/api/dashboard/stream');
|
// kinds= matches SSE_HANDLERS below verbatim — narrows this from all
|
||||||
|
// 17 wire kinds down to the 3 this page acts on. This page was one
|
||||||
|
// of 4 unfiltered `/api/dashboard/stream` subscribers before this
|
||||||
|
// (subscription discipline, part 1 of the dashboard-event-stream-
|
||||||
|
// split issue).
|
||||||
|
const es = openStream(
|
||||||
|
'/api/dashboard/stream?kinds=rebuild_queue_changed,meta_inputs_changed,meta_update_running',
|
||||||
|
);
|
||||||
if (es) {
|
if (es) {
|
||||||
es.onmessage = (e) => {
|
es.onmessage = (e) => {
|
||||||
let ev;
|
let ev;
|
||||||
|
|
|
||||||
|
|
@ -509,7 +509,15 @@ async function init() {
|
||||||
|
|
||||||
await refreshState();
|
await refreshState();
|
||||||
|
|
||||||
const es = openStream('/api/dashboard/stream');
|
// kinds= matches SSE_HANDLERS below verbatim — narrows this from all
|
||||||
|
// 17 wire kinds down to the 4 this page acts on. This page was one
|
||||||
|
// of 4 unfiltered `/api/dashboard/stream` subscribers before this
|
||||||
|
// (subscription discipline, part 1 of the dashboard-event-stream-
|
||||||
|
// split issue).
|
||||||
|
const es = openStream(
|
||||||
|
'/api/dashboard/stream?kinds=tombstones_changed,container_state_changed,' +
|
||||||
|
'capabilities_changed,tool_groups_changed',
|
||||||
|
);
|
||||||
if (es) {
|
if (es) {
|
||||||
es.onmessage = (e) => {
|
es.onmessage = (e) => {
|
||||||
let ev;
|
let ev;
|
||||||
|
|
|
||||||
|
|
@ -384,8 +384,12 @@ import '@hive/shared/hive-tab-strip.js';
|
||||||
loadContainerLists();
|
loadContainerLists();
|
||||||
|
|
||||||
// Subscribe to the dashboard SSE stream for audit live-appends.
|
// Subscribe to the dashboard SSE stream for audit live-appends.
|
||||||
|
// kinds= narrows this from all 17 wire kinds down to the 1 this page
|
||||||
|
// acts on. This page was one of 4 unfiltered `/api/dashboard/stream`
|
||||||
|
// subscribers before this (subscription discipline, part 1 of the
|
||||||
|
// dashboard-event-stream-split issue).
|
||||||
{
|
{
|
||||||
const es = openStream('/api/dashboard/stream');
|
const es = openStream('/api/dashboard/stream?kinds=audit_entry_added');
|
||||||
if (es) {
|
if (es) {
|
||||||
es.onmessage = (e) => {
|
es.onmessage = (e) => {
|
||||||
let ev;
|
let ev;
|
||||||
|
|
|
||||||
|
|
@ -314,12 +314,25 @@ window.marked = marked;
|
||||||
tool_groups_changed: applyToolGroupsChanged,
|
tool_groups_changed: applyToolGroupsChanged,
|
||||||
};
|
};
|
||||||
(function bindDashboardStream() {
|
(function bindDashboardStream() {
|
||||||
// Route through the SharedWorker so all open hyperhive tabs share
|
// Route through the SharedWorker so all open hyperhive tabs on the
|
||||||
// one upstream SSE connection — see docs/web-ui.md (SSE multiplexing
|
// SAME kinds= filter share one upstream SSE connection — see
|
||||||
// paragraph) for the design + Firefox throttling motivation.
|
// docs/web-ui/shape.md (SSE multiplexing paragraph) for the design
|
||||||
// `openStream` returns an EventSource-shaped facade with a graceful
|
// + Firefox throttling motivation. `openStream` returns an
|
||||||
// direct-EventSource fallback when SharedWorker isn't supported.
|
// EventSource-shaped facade with a graceful direct-EventSource
|
||||||
const es = openStream('/api/dashboard/stream');
|
// fallback when SharedWorker isn't supported.
|
||||||
|
//
|
||||||
|
// kinds= matches MUTATION_HANDLERS below verbatim, plus `sent`
|
||||||
|
// (checked separately, just above, for the operator inbox) —
|
||||||
|
// narrows this from all 17 wire kinds down to the 13 this page
|
||||||
|
// actually acts on. This page was one of 4 unfiltered
|
||||||
|
// `/api/dashboard/stream` subscribers before this (subscription
|
||||||
|
// discipline, part 1 of the dashboard-event-stream-split issue).
|
||||||
|
const es = openStream(
|
||||||
|
'/api/dashboard/stream?kinds=sent,approval_added,approval_resolved,' +
|
||||||
|
'question_added,question_resolved,transient_set,transient_cleared,' +
|
||||||
|
'container_state_changed,container_removed,rebuild_queue_changed,' +
|
||||||
|
'schedules_changed,capabilities_changed,tool_groups_changed',
|
||||||
|
);
|
||||||
es.onmessage = (e) => {
|
es.onmessage = (e) => {
|
||||||
let ev;
|
let ev;
|
||||||
try { ev = JSON.parse(e.data); } catch { return; }
|
try { ev = JSON.parse(e.data); } catch { return; }
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue