Repository navigation
ui: show each node's sandbox and slot occupancy - #1252
Conversation
The nodes page listed nodes with include_occupancy=false, so it never showed how many sandboxes a node holds, how many snapshots exist only on its disk, or whether its network slots are degraded or quarantined, all of which the admin API returns on request. An operator choosing a node to drain, or looking for the full one, had to open each node's sandbox drawer. The list now asks for occupancy and shows a Sandboxes column: active sandboxes, node-local snapshots when there are any, and unhealthy network slots when there are any, with the full slot counts in a tooltip.
|
Thanks for opening this pull request! A SPACE maintainer will take a look. CONTRIBUTING.md explains how we review outside contributions. |
The nodes page refreshes its node list every second while visible. With occupancy enabled, every one of those refreshes asked the admin API for include_occupancy=true, which counts sandbox and snapshot rows per node: once a second for every open nodes page. The one-second refresh is metadata-only again. Occupancy is read when the page loads, on Refresh, after a node action and every 30 seconds while the page is visible, and merged into the rows by node ID; the Sandboxes column's tooltip says how long ago the counts were taken.
Review follow-ups for the nodes page's occupancy column:
- Every node read (the one-second refresh, the initial load, Refresh
and the reload after a node action) is metadata-only. Occupancy, the
per-node sandbox and snapshot counts, is a separate best-effort read
afterwards and every 30 s; a failure marks the counts stale instead of
failing the load or the action.
- Network slots come from each row's own node response, which carries
them every second, rather than from the occupancy read.
- Occupancy responses for an older request or another role filter are
dropped.
- The counts are marked stale when the last occupancy read failed or is
older than two intervals; the tooltip gives their age ("counted 12s
ago", not "ago ago") and prints missing slot fields as "—".
Withdrawing this approval for now. Any feedback above still stands.
johnlouie-pplx
left a comment
There was a problem hiding this comment.
Approving with one nonblocking follow-up. At 27077d3, I checked the counts against the API contracts; the UI build passed, and mocked-API checks distinguished zero, missing and failed counts.
In ui/src/app/dashboard/nodes/page.tsx, the Sandboxes cell returns early when the sandbox count is unavailable, hiding the unhealthy-slot warning even though slot data comes from a separate read. Could we keep that warning beside "could not count" or "not computed", and say "sandbox counts are stale" so the tooltip doesn't imply that the slot sample has the same age?
Summary
The nodes page now shows how full each node is.
It listed nodes with
include_occupancy=false, so it never showed:The admin API returns all of these on request. An operator choosing a node to drain, or looking for the full one, had to open each node's sandbox drawer.
Node reads stay metadata-only (
include_occupancy=false), as onmain: the one-second refresh, the initial load, Refresh and the reload after a node action. The per-node sandbox and snapshot counts come from a separate best-effortinclude_occupancy=trueread, made after the page loads, on Refresh, after a node action and every 30 seconds while the page is visible. The page merges them into the rows by node ID and drops any response for an older request or another role filter. A new Sandboxes column shows:A tooltip gives the full slot counts, from each row's own node response, and when the sandbox counts were taken. The counts are marked "stale" when the last occupancy read failed or is older than 60 seconds, and a failed read never fails the page or an action.
Stack
#1256 (the node page) is stacked on this PR. It edits
ui/src/app/dashboard/nodes/page.tsx, which #1242 and #1250 also touch; whichever merges later may need a small rebase.Validation
npm ci,npm test(50 pass) andnpm run buildinui/.main(production build) and on this branch (the Kindspace-uiimage). The nodes step checks that each node shows its active count.main.Visual confirmation
Severity and risk
Severity: medium. Capacity is the first thing to check before draining or placing work.
Risk: low. The page adds one occupancy query (per-node sandbox and snapshot counts) every 30 seconds per open nodes page, plus one on load, on Refresh and after each node action. Plain
space-admin-cli list-nodesreads metadata only (include_occupancy=false). Drain ranking (list-nodes --sort drainability) andget-node --diagnosticsare the other consumers of this counting query. Roll back by reverting the commit.AI assistance: Claude Code wrote the code and this description, and ran the validation; a maintainer reviews it.