import { Show, createMemo, type Component } from "solid-js"; import type { BackendSnapshot, PoolBackendSnapshot } from "../types"; import StatusBadge from "../components/StatusBadge"; import ProbeHeartbeat from "../components/ProbeHeartbeat"; import Flash from "../components/Flash"; import BackendActionsMenu from "../components/BackendActionsMenu"; import { lastTransitionAge, lbBucketsFor, state as appState } from "../stores/state"; import { isAdmin } from "../stores/mode"; type Props = { maglevd: string; frontend: string; pool: string; // showPool=true renders the pool name in the first column. Set // only on the first backend row of each pool; subsequent rows in // the same pool leave the cell blank, giving the "grouped table" // look where the pool label appears once above its members. showPool: boolean; // poolActive=false means every backend in this row's pool has // effective_weight=0 right now — a standby fallback or a fully // drained primary. The row is rendered dimmer so the operator // can scan which pool is actually carrying traffic. poolActive: boolean; backend: BackendSnapshot; poolBackend: PoolBackendSnapshot; }; const BackendRow: Component = (props) => { const b = () => props.backend; // Subscribed lookup: lbBucketsFor reads from the reactive store, so // the cell re-renders the moment a "lb-state" SSE event mutates the // map. A missing entry (VPP disconnected, backend not yet programmed) // renders as an em-dash; an explicit 0 means "in VPP, drained". // createMemo guarantees Flash only sees a new value when the leaf // actually changed — without it, any spurious upstream re-run (e.g. // a sibling backend's transition triggering recomputeDerivedState) // would pop the bucket cell on every backend in the table. const bucketsLabel = createMemo(() => { const v = lbBucketsFor(appState.byName[props.maglevd], props.frontend, b().name); return v === undefined ? "—" : v; }); return ( {props.showPool ? props.pool : ""} {b().name} {b().address} {lastTransitionAge(b().last_transition)} ); }; export default BackendRow;