feature(web/monitor): live tail view + pause/resume + bounded buffer#173
Open
jamby77 wants to merge 2 commits into
Open
feature(web/monitor): live tail view + pause/resume + bounded buffer#173jamby77 wants to merge 2 commits into
jamby77 wants to merge 2 commits into
Conversation
12 tasks
ab6acde to
36dedbc
Compare
0f03629 to
e8e7644
Compare
36dedbc to
b90faee
Compare
e8e7644 to
b90faee
Compare
8aefbac to
a86cd6b
Compare
The Sessions table rows are now clickable links to a per-session detail
page that streams the live MONITOR output via the TailGateway. Lines
appear in real time, the Pause button freezes the local view while the
gateway buffers server-side, and Resume drains the buffered window in
order.
- New useMonitorTail(sessionId, bufferSize=5000) hook:
- Opens ws://localhost:3001/monitor/ws?sessionId=X (dev) or
/api/monitor/ws (prod, same-origin) per env.
- Accumulates incoming MONITOR text lines in a ref-buffer; flushes
a snapshot to React state at most once per animation frame so the
UI batches updates at ~60 Hz under thousands of lines/sec.
- Bounds the buffer at 5 000 lines — when it overflows the oldest
drop and bufferTrimmed flips true.
- Maintains a separate totalReceived counter (NOT bounded) so the
UI can show "N lines received · showing last K (older lines
dropped)".
- pause()/resume() send {type:'pause'|'resume'} control messages;
the server-side per-viewer buffer drains in original order.
- Status state tracks connecting → streaming → paused → session_ended
| historical_complete | closed | error.
- New TailView component: status badge, line counter, dropped-lines
notice, pause/resume controls (only when live), monospace scrollable
panel that auto-scrolls to bottom unless the user scrolls up
(followBottomRef ref).
- New MonitorSession page (route: /monitor/sessions/:id) with header
showing session id, started timestamp, source, line count, and
termination reason; live tail panel below.
- SessionsTable rows are now clickable and navigate to the detail page.
- ESLint disable for react-hooks/set-state-in-effect on the connection-
reset block: those setStates are pre-WS-open initial-state restoration,
React 18 batches them into a single commit, no cascade is possible.
Documented inline.
Verification (Playwright, live):
- Started a 5-min session, navigated to /monitor/sessions/:id, sent
80 SETs from another terminal → all 80 SET lines streamed into the
view in real time alongside ongoing INFO polling; total reached 173
lines.
- Clicked Pause → status badge flipped to amber "Paused"; tail froze
at 37 lines. Sent 100 SETs against Valkey while paused → still 37
shown. Clicked Resume → instantly drained to 278 lines, all 100
paused SETs included in original order.
Screenshots:
- docs/assets/pr10-live-tail.png (live tail mid-session)
- docs/assets/pr10-tail-after-resume.png (post-resume drain)
Part of PR 10 of 25 in
docs/plans/specs/monitor-command/plan-implementation.md.
Self-review fixes:
- useMonitorTail cleanup detaches onopen/onmessage/onerror/onclose
before calling ws.close(). close() is async, so without nulling
the handlers the old socket's onclose can fire after a new socket
has been created and flip the new connection's status to 'closed'.
- MonitorSession used listSessions({ limit: 100 }) and filtered
client-side, which silently failed for older sessions or sessions
on a non-current connection. Switched to monitorApi.getSession(id)
(added) which hits GET /monitor/sessions/:id.
2d42d85 to
997fbc8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR 10 of 25 in
docs/plans/specs/monitor-command/plan-implementation.md. Stacked on top of #172 (PR 9). Sessions table rows are now clickable, navigating to a per-session detail page that streams the live MONITOR output via the TailGateway from PR 7. Lines appear in real time, Pause freezes the local view while the gateway buffers server-side, Resume drains the buffered window in order.useMonitorTail(sessionId, bufferSize=5000)hookws://localhost:3001/monitor/ws?sessionId=X(dev) or/api/monitor/ws(prod, same-origin) per env.requestAnimationFrameso the UI batches updates at ~60 Hz under thousands of lines/sec without per-line re-renders.bufferTrimmedflips true.totalReceivedcounter (NOT bounded) so the UI can show"N lines received · showing last K (older lines dropped)".pause()/resume()send{type:'pause'|'resume'}control messages; the server-side per-viewer buffer drains in original order.statusstate tracksconnecting → streaming → paused → session_ended | historical_complete | closed | error.TailView + MonitorSession page
followBottomRef)./monitor/sessions/:idwith header showing session id, started timestamp, source, line count, termination reason.SessionsTablerows are clickable and navigate to the detail page.Test plan
pnpm --filter web exec tsc --noEmit→ exit 0pnpm --filter web exec eslint src/hooks/useMonitorTail.ts src/pages/monitor/tail-view.tsx src/pages/MonitorSession.tsx→ no errorsMONITOR_DEV_PREVIEW=true pnpm dev:apiandVITE_MONITOR_DEV_PREVIEW=true pnpm dev:webcurl -X POST -H 'content-type: application/json' -d '{"connectionId":"env-default","durationMs":300000}' http://localhost:3001/monitor/sessionsdocker exec betterdb-monitor-valkey valkey-cli -a devpassword -r 80 SET k v→ SET lines stream in within ~1 sNotes for reviewers
@tanstack/react-virtualthen; flagged.useMonitorTail.tsforreact-hooks/set-state-in-effecton the connection-reset block. Those setStates are pre-WS-open initial-state restoration; React 18 batches them into a single commit, no cascade is possible. Documented inline.CliGatewayand the rest of the gateway — handshake-time gate viaMONITOR_DEV_PREVIEW+ demo-host check. No per-message auth.session_endedinstead ofhistorical_complete. Both produce the same close + status frame, so the UI handles them identically.docs/assets/:pr10-live-tail.png(live tail mid-session)pr10-tail-after-resume.png(post-resume drain)Stacked PR
Base branch is
feature/monitor-web-start-session-modal(#172), so the diff shown is ONLY PR 10 changes.