mirror of
https://github.com/jmcorgan/fips.git
synced 2026-08-12 01:27:32 +00:00
b3f2018fce5fed3d414ae9e1f7d9d869defd0b3e
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5fc2359432 |
fipstop: TUI overhaul with render-snapshot harness and navigation model
Reworks the fipstop TUI across its rendering, the control read surface it draws from, and its interaction model, on a machine-verified base. Test infrastructure: - Add a ratatui TestBackend snapshot harness (testkit + snapshots modules) that renders any ui::draw_* into an in-memory Buffer from canned show_* JSON and asserts the text grid plus per-cell style. Layout, columns, alignment, labels, grouping, and colour are now checkable under cargo test; every render below ships a snapshot. Control read surface (each new field emitted byte-identically on the live and off-loop builders, published once from the tick, with schema fixtures regenerated and the parity asserts holding): - show_status: effective persistence (persistent || nsec.is_some()); root and is_root; and a per-configured-transport-type peer-count map in which idle-but-configured types stay visible at zero. - show_peers: per-peer effective_depth (depth + link_cost, the value evaluate_parent ranks on), null when unmeasured or coordless so fipstop never recomputes it. - show_tree: root_npub, resolved once daemon-side (self when root, an attested peer npub, or an identity-cache hit). - show_bloom: the last-actually-sent uptree filter fill ratio and subtree estimate, null for a root or before the first announce. - show_mmp: session-layer srtt, loss, and etx trend labels. Rendering: - Display a 6-byte non-UTF-8 TransportAddr as a colon-separated MAC at the type layer, so daemon logs, fipsctl, and JSON consumers all benefit; non-6-byte payloads stay bare hex. - Right-justify the Bloom Peer Filters numerics into aligned fixed-width columns, render the Routing panes through a kv_lines helper that shares one value column across a key-value group, and right-justify the Graphs by-peer summary columns. - Truncate an over-long peer name (the npub shown when no friendly name exists) in the Tree, Bloom, and MMP peer lists so it no longer runs into the next column. - Group the Peers table by role (parent, then STP children, then other) and render it as a full grouped view with styled group labels and blank separators; the selection stays a peer index and the cursor only ever lands on a peer row. Apply the same role grouping to the Tree and Bloom peer lists, joining each peer's role from the peers view by node address. - Show min in the Graphs plot titles, rest a steady non-zero metric on the baseline as a row of dots, render a genuine zero as an empty plot, and keep a distinct no-data placeholder. - Replace the metric-by-peer grid, which squeezed plots to nothing once peers overflowed, with a master/detail Graphs view: a scrollable per-peer summary list that expands (Enter) to a full-pane btop plot, with up/down to flip peer, n/N to switch statistic, m to cycle mode, and Esc to return. - Put inline colored trend arrows on the Link and Session MMP values (drawn only on a rising or falling trend, with a fixed blank slot when stable so the value columns stay aligned), via a shared helper. - Cycle column sorting on the Link MMP, Session MMP, and Graphs by-peer tables (one key cycles the active column, another toggles direction), with the active column marked in each table's header. - Render the new daemon-surfaced fields: the dashboard root line (a self-is-root marker, otherwise a truncated root hex), a transports-by-type line, and an "approx. mesh estimate" line; an effective_depth column and lines on the Peers, peer-detail, and Tree sites from the single daemon derivation, showing a dash placeholder when unmeasured rather than a misleading zero; the full Tree root hex plus an Npub line; and the Bloom uptree fill and subtree-estimate lines. Interaction model: - Add a declarative keybinding registry keyed by (Tab, UiMode) that both the context footer and the ? help overlay render from, so the two cannot drift; a test asserts every registry key has a dispatch handler. - Add a modal ? help overlay, and a context-aware footer that shows the current state's actions first, drops global hints when the terminal is narrow, and always keeps a Help affordance as the overflow path. - Generalize per-pane focus and scroll state on App, wired across the Tree, Filters, Routing, and MMP tabs (f cycles pane focus and the focused pane scrolls instead of clipping its overflow); on the MMP tab the column sort acts on the focused pane. Esc deselects the active row when no detail is open (detail-close still takes priority). - Add a Del-disconnect confirmation modal naming the peer, the only state-mutating action, issuing the control-socket disconnect on confirm and noting that the peer stays disconnected until manually reconnected. |
||
|
|
81cd10d5db |
control: serve the full show_* read surface off the rx_loop via a read-snapshot plane
Complete the control-plane read-isolation work: every pure-read show_* query now renders in the control accept task from published read snapshots, so none round-trips the data-plane receive loop. Only the mutating connect/disconnect commands still reach that loop. Three subsystem snapshots are published via ArcSwap and served through the read handle's snapshot_dispatch: - A routing read view (spanning tree, bloom filters, coordinate cache, identity cache, and the discovery F-queue summary scalars), published from the tick, serving show_tree/show_bloom/show_cache/show_routing/ show_identity_cache. - A per-entity read view (peers, sessions, links, connections, transports, and the MMP link/session views) as Vec<Arc<Row>> tables reconciled against the prior snapshot so a republish reuses unchanged rows by pointer and re-allocates only changed or new rows, keeping the per-tick publish cost bounded as the peer/session count grows. Serves show_peers/show_sessions/show_links/show_connections/show_transports/ show_mmp. - The stats snapshot is extended with the peer-ACL status and a per-peer metadata map (is_active, npub, display name), resolved at publish time, serving show_acl and the two per-peer stats queries. Display names and other cross-subsystem fields are resolved at publish time; time-relative fields are derived at render time from captured absolute timestamps, so rendered output is byte-identical to the prior on-loop handlers, which are retained as the equality oracle. With every read query served off-loop, the show_* branch is removed from the rx_loop control handler and the now-dead on-loop dispatcher deleted. The snapshot projections are forward-compatible with the later structural extraction of the derived-state and session tables: they become thin views over the extracted types without changing the read-handle interface. |
||
|
|
c77e564462 |
control: serve high-traffic show_* queries off the rx_loop hot path
Introduce a read-snapshot plane so pure-snapshot control queries render in the control-socket task instead of round-tripping the rx_loop, removing the head-of-line coupling that let a busy or slow rx_loop time out fipsctl and fipstop observability. - ControlReadHandle: a cloneable bundle the control accept loop holds, over the node's already-shared NodeContext and MetricsRegistry plus an ArcSwap-published StatsSnapshot. A snapshot_dispatch seam serves cut-over commands off-loop and falls through to the rx_loop for the rest, keeping the rx_loop's ownership of Node intact. - StatsSnapshot is published from the tick (the natural and sole mutator of stats_history), carrying the history rings plus the scalar gauges and counts show_status reports. Readers serve the latest snapshot unconditionally, with staleness bounded by the tick interval and no IO_TIMEOUT-coupled fallback. - Off-loop now: show_status, show_stats_history, show_stats_all_history, show_listening_sockets, show_stats_list, and a new counter-only show_metrics (exposed as fipsctl "stats metrics", the enabler for a Prometheus scraper at no hot-path cost). Queries that need live per-entity state (peers, links, sessions, routing, and the per-peer stats variants) stay on the rx_loop path pending later phases. Quartet green; forward-merge to next verified clean. |