Fix stats query storm: stabilize time params to 10s granularity
PerformanceTab and RouteHeader computed new Date().toISOString() on every render, producing unique millisecond timestamps that busted the React Query cache key — causing continuous refetches (every few ms instead of 10s). Round timestamps to 10-second boundaries with useMemo so the query key stays stable between renders. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import { useMemo } from 'react';
|
||||||
import { useExecutionStats, useStatsTimeseries } from '../../api/queries/executions';
|
import { useExecutionStats, useStatsTimeseries } from '../../api/queries/executions';
|
||||||
import { StatCard } from '../../components/shared/StatCard';
|
import { StatCard } from '../../components/shared/StatCard';
|
||||||
import { ThroughputChart } from '../../components/charts/ThroughputChart';
|
import { ThroughputChart } from '../../components/charts/ThroughputChart';
|
||||||
@@ -18,9 +19,16 @@ function pctChange(current: number, previous: number): { text: string; direction
|
|||||||
return { text: `${arrow} ${Math.abs(pct).toFixed(1)}% vs yesterday`, direction: pct > 0 ? 'up' : 'down' };
|
return { text: `${arrow} ${Math.abs(pct).toFixed(1)}% vs yesterday`, direction: pct > 0 ? 'up' : 'down' };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Round epoch-ms down to the nearest 10 s so the query key stays stable between renders. */
|
||||||
|
function stableIso(epochMs: number): string {
|
||||||
|
return new Date(Math.floor(epochMs / 10_000) * 10_000).toISOString();
|
||||||
|
}
|
||||||
|
|
||||||
export function PerformanceTab({ group, routeId }: PerformanceTabProps) {
|
export function PerformanceTab({ group, routeId }: PerformanceTabProps) {
|
||||||
const timeFrom = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
|
const [timeFrom, timeTo] = useMemo(() => {
|
||||||
const timeTo = new Date().toISOString();
|
const now = Date.now();
|
||||||
|
return [stableIso(now - 24 * 60 * 60 * 1000), stableIso(now)];
|
||||||
|
}, [Math.floor(Date.now() / 10_000)]);
|
||||||
|
|
||||||
// Use scoped stats/timeseries via group+routeId query params
|
// Use scoped stats/timeseries via group+routeId query params
|
||||||
const { data: stats } = useExecutionStats(timeFrom, timeTo, routeId, group);
|
const { data: stats } = useExecutionStats(timeFrom, timeTo, routeId, group);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { useMemo } from 'react';
|
||||||
import type { DiagramLayout } from '../../api/types';
|
import type { DiagramLayout } from '../../api/types';
|
||||||
import { useExecutionStats } from '../../api/queries/executions';
|
import { useExecutionStats } from '../../api/queries/executions';
|
||||||
import styles from './RoutePage.module.css';
|
import styles from './RoutePage.module.css';
|
||||||
@@ -10,7 +11,10 @@ interface RouteHeaderProps {
|
|||||||
|
|
||||||
export function RouteHeader({ group, routeId, layout }: RouteHeaderProps) {
|
export function RouteHeader({ group, routeId, layout }: RouteHeaderProps) {
|
||||||
const nodeCount = layout?.nodes?.length ?? 0;
|
const nodeCount = layout?.nodes?.length ?? 0;
|
||||||
const timeFrom = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
|
const timeFrom = useMemo(
|
||||||
|
() => new Date(Math.floor(Date.now() / 10_000) * 10_000 - 24 * 60 * 60 * 1000).toISOString(),
|
||||||
|
[Math.floor(Date.now() / 10_000)],
|
||||||
|
);
|
||||||
const { data: stats } = useExecutionStats(timeFrom, undefined, routeId, group);
|
const { data: stats } = useExecutionStats(timeFrom, undefined, routeId, group);
|
||||||
|
|
||||||
const successRate = stats && stats.totalCount > 0
|
const successRate = stats && stats.totalCount > 0
|
||||||
|
|||||||
Reference in New Issue
Block a user