From f64dc32dd94172f6bd755997d17038c5b906cf58 Mon Sep 17 00:00:00 2001 From: npub1jmc9dt2lyvzu3h0kxlwxt5zg4fxp9476awyxw6gwxn72g6cw7exqs64whm <96f056ad5f2305c8ddf637dc65d048aa4c12d7daeb8867690e34fca46b0ef64c@sprout-oss.stage.blox.sqprod.co> Date: Wed, 8 Jul 2026 10:16:25 -0400 Subject: [PATCH] perf(desktop): drop redundant 30s polls on personas/teams/managed agents L6 finding: usePersonasQuery, useTeamsQuery, and useManagedAgentsQuery's idle branch each ran a 30s refetchInterval that duplicated an existing event-driven refresh path. Inbound relay changes to PERSONA/TEAM/MANAGED_AGENT records emit agents-data-changed (personas/mod.rs), which useAgentsDataRefresh coalesces into a query invalidate (200ms window). The 30s poll was belt-and-suspenders disk-read IPC on top of correct event invalidation. Removed the interval from personas and teams entirely. For managed agents, kept the 5s branch for locally-running agents (process state can change with no relay event, so that poll is their only liveness signal) and dropped the idle 30s fallback (control-plane changes have the event path; the 5s branch already captures the running->stopped transition on its last poll, and user actions invalidate directly). Co-authored-by: Tyler Longwell Signed-off-by: Tyler Longwell --- desktop/src/features/agents/hooks.ts | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/desktop/src/features/agents/hooks.ts b/desktop/src/features/agents/hooks.ts index 1ff313a92..5289d0d08 100644 --- a/desktop/src/features/agents/hooks.ts +++ b/desktop/src/features/agents/hooks.ts @@ -176,7 +176,10 @@ export function usePersonasQuery() { queryKey: personasQueryKey, queryFn: listPersonas, staleTime: 30_000, - refetchInterval: 30_000, + // No refetchInterval: inbound relay changes to personas emit + // `agents-data-changed`, which `useAgentsDataRefresh` coalesces into an + // invalidate (200ms window). The 30s poll was belt-and-suspenders on top of + // that event path — redundant disk-read IPC. }); } @@ -231,12 +234,14 @@ export function useManagedAgentsQuery(options?: { enabled?: boolean }) { staleTime: 5_000, refetchInterval: (query) => { const agents = query.state.data as ManagedAgent[] | undefined; - // Only local "running" agents need fast polling (process state can - // change). "deployed" is static control-plane state — presence polling - // handles the live signal for remote agents separately. + // Only local "running" agents need polling: process state can change + // with no relay event to signal it, so this poll is the only liveness + // path for them. When nothing is running there IS an event path — + // `agents-data-changed` (control-plane changes) — so the idle branch + // drops its poll entirely rather than falling back to 30s. return agents?.some((agent) => agent.status === "running") ? 5_000 - : 30_000; + : false; }, }); } @@ -689,7 +694,9 @@ export function useTeamsQuery() { queryKey: teamsQueryKey, queryFn: listTeams, staleTime: 30_000, - refetchInterval: 30_000, + // No refetchInterval: inbound relay team changes emit `agents-data-changed` + // (handled by useAgentsDataRefresh). Same redundant-poll removal as + // usePersonasQuery. }); }