fix(dashboard): guard setMetricsById against same-value calls to end loop

Even with primitive useEffect deps, TanStack Query or React concurrent
rendering can cause onMetrics to fire with identical values mid-render-cycle.
Add a ref-based equality check in Dashboard.onMetrics: if all five metric
values are unchanged, skip setMetricsById entirely — no state update, no
Dashboard re-render, loop terminates.

Also fixes vi.fn<TFunction>() typing in server-workspace-rows.test.tsx to
satisfy tsc (Vitest 4 single-type-arg signature).
This commit is contained in:
Offending Commit
2026-06-03 17:47:59 -05:00
parent 9cc8637dc7
commit 3b88a41afd
2 changed files with 18 additions and 5 deletions

View File

@@ -1,7 +1,7 @@
import { Link, useNavigate } from "@tanstack/react-router";
import { motion } from "framer-motion";
import { Boxes, LayoutDashboard, Network, Settings as SettingsIcon } from "lucide-react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import {
computeFleetAggregates,
DEFAULT_ROW_METRICS,
@@ -28,6 +28,7 @@ export function Dashboard() {
const navigate = useNavigate();
const [serverFilter, setServerFilter] = useState<string>(ALL_SERVERS);
const [metricsById, setMetricsById] = useState<Record<string, FleetRowMetrics>>({});
const lastMetrics = useRef<Record<string, FleetRowMetrics>>({});
useEffect(() => {
if (serverFilter !== ALL_SERVERS && !instances.find((i) => i.id === serverFilter)) {
@@ -36,6 +37,17 @@ export function Dashboard() {
}, [instances, serverFilter]);
const onMetrics = useCallback((id: string, m: FleetRowMetrics) => {
const prev = lastMetrics.current[id];
if (
prev &&
prev.workspaceCount === m.workspaceCount &&
prev.conclusionCount === m.conclusionCount &&
prev.queueActive === m.queueActive &&
prev.queuePending === m.queuePending &&
prev.health === m.health
)
return;
lastMetrics.current = { ...lastMetrics.current, [id]: m };
setMetricsById((prev) => ({ ...prev, [id]: m }));
}, []);