Fix: Rename metrics queries, always refetch queue metrics, change default refetch interval, configurable WAL poll limit (#2346)

* fix: improve query naming + change refetch interval for queue metrics

* fix: only enable queue metrics query when it's open

* feat: change default

* fix: change storage key to clear cache

* fix: queue metrics loading state

* feat: introduce poll limit with default of 1000

* feat: set WAL poll limit

* debug: log line to test

* fix: export helper

* fix: rm debug
This commit is contained in:
matt
2025-09-25 20:44:39 -04:00
committed by GitHub
parent 025f42af74
commit 126ff3771b
11 changed files with 82 additions and 59 deletions

View File

@@ -28,13 +28,13 @@ interface RefetchIntervalProviderProps {
children: ReactNode;
}
const STORAGE_KEY = 'app-refetch-interval';
const STORAGE_KEY = 'app-default-refetch-interval';
export const RefetchIntervalProvider = ({
children,
}: RefetchIntervalProviderProps) => {
const [storedInterval, setStoredInterval] =
useLocalStorageState<RefetchIntervalOption>(STORAGE_KEY, 'off');
useLocalStorageState<RefetchIntervalOption>(STORAGE_KEY, '10s');
const [isFrozen, setIsFrozen] = useLocalStorageState<boolean>(
'app-refetch-interval-frozen',
false,

View File

@@ -29,6 +29,7 @@ import { useRunsContext } from '../hooks/runs-provider';
import { DocsButton } from '@/components/v1/docs/docs-button';
import { docsPages } from '@/lib/generated/docs';
import { useRefetchInterval } from '@/contexts/refetch-interval-context';
import { Loading } from '@/components/v1/ui/loading';
export interface RunsTableProps {
headerClassName?: string;
@@ -99,11 +100,12 @@ export function RunsTable({ headerClassName }: RunsTableProps) {
numPages,
isRunsLoading,
isRunsFetching,
isMetricsLoading,
isMetricsFetching,
isStatusCountsFetching,
isStatusCountsLoading,
isQueueMetricsLoading,
isRefetching,
metrics,
tenantMetrics,
runStatusCounts,
queueMetrics,
actionModalParams,
selectedActionType,
pagination,
@@ -203,8 +205,8 @@ export function RunsTable({ headerClassName }: RunsTableProps) {
return () => clearInterval(interval);
}, [filters, filters.isCustomTimeRange, filters.updateCurrentTimeWindow]);
const hasLoaded = !isRunsLoading && !isMetricsLoading;
const isFetching = !hasLoaded && (isRunsFetching || isMetricsFetching);
const hasLoaded = !isRunsLoading && !isStatusCountsLoading;
const isFetching = !hasLoaded && (isRunsFetching || isStatusCountsFetching);
return (
<div className="flex flex-col h-full overflow-hidden gap-y-2">
@@ -223,14 +225,15 @@ export function RunsTable({ headerClassName }: RunsTableProps) {
<DialogTitle>Queue Metrics</DialogTitle>
</DialogHeader>
<Separator />
{tenantMetrics && (
{!queueMetrics || isQueueMetricsLoading ? (
<Loading />
) : (
<CodeHighlighter
language="json"
className="max-h-[400px] overflow-y-auto"
code={JSON.stringify(tenantMetrics || '{}', null, 2)}
code={JSON.stringify(queueMetrics || '{}', null, 2)}
/>
)}
{isMetricsLoading && 'Loading...'}
</DialogContent>
</Dialog>
)}
@@ -262,7 +265,7 @@ export function RunsTable({ headerClassName }: RunsTableProps) {
...(!hideCounts
? [
<div key="metrics" className="flex justify-start mr-auto">
{metrics.length > 0 ? (
{runStatusCounts.length > 0 ? (
<V1WorkflowRunsMetricsView />
) : (
<Skeleton className="max-w-[800px] w-[40vw] h-8" />

View File

@@ -49,7 +49,7 @@ function MetricBadge({
status: V1TaskStatus;
className?: string;
}) {
const { filters, metrics } = useRunsContext();
const { filters, runStatusCounts } = useRunsContext();
const currentStatuses = useMemo(
() => filters.apiFilters.statuses || [],
[filters.apiFilters.statuses],
@@ -86,7 +86,7 @@ function MetricBadge({
[currentStatuses, setStatuses],
);
const metric = metrics.find((m) => m.status === status);
const metric = runStatusCounts.find((m) => m.status === status);
if (!metric) {
return null;

View File

@@ -62,11 +62,12 @@ type RunsContextType = {
numPages: number;
isRunsLoading: boolean;
isRunsFetching: boolean;
isMetricsLoading: boolean;
isMetricsFetching: boolean;
isStatusCountsLoading: boolean;
isStatusCountsFetching: boolean;
isQueueMetricsLoading: boolean;
isRefetching: boolean;
metrics: V1TaskRunMetrics;
tenantMetrics: object;
runStatusCounts: V1TaskRunMetrics;
queueMetrics: object;
isActionModalOpen: boolean;
isActionDropdownOpen: boolean;
selectedActionType: ActionType | null;
@@ -176,20 +177,22 @@ export const RunsProvider = ({
);
const {
metrics,
tenantMetrics,
isLoading: isMetricsLoading,
isFetching: isMetricsFetching,
runStatusCounts,
queueMetrics,
isStatusCountsLoading,
isStatusCountsFetching,
refetch: refetchMetrics,
isRefetching: isMetricsRefetching,
isStatusCountsRefetching,
isQueueMetricsLoading,
} = useMetrics({
workflow,
parentTaskExternalId,
createdAfter: filters.apiFilters.since,
additionalMetadata: filters.apiFilters.additionalMetadata,
showQueueMetrics,
});
const isRefetching = isRunsRefetching || isMetricsRefetching;
const isRefetching = isRunsRefetching || isStatusCountsRefetching;
const value = useMemo<RunsContextType>(
() => ({
@@ -200,11 +203,12 @@ export const RunsProvider = ({
numPages,
isRunsLoading,
isRunsFetching,
isMetricsLoading,
isMetricsFetching,
isStatusCountsFetching,
isStatusCountsLoading,
isQueueMetricsLoading,
isRefetching,
metrics,
tenantMetrics,
runStatusCounts,
queueMetrics,
isActionModalOpen,
isActionDropdownOpen,
actionModalParams,
@@ -247,10 +251,11 @@ export const RunsProvider = ({
numPages,
isRunsLoading,
isRunsFetching,
isMetricsLoading,
isMetricsFetching,
metrics,
tenantMetrics,
isStatusCountsFetching,
isStatusCountsLoading,
isQueueMetricsLoading,
runStatusCounts,
queueMetrics,
isActionModalOpen,
isActionDropdownOpen,
hideMetrics,

View File

@@ -8,16 +8,24 @@ export const useMetrics = ({
parentTaskExternalId,
additionalMetadata,
createdAfter,
showQueueMetrics,
}: {
workflow: string | undefined;
parentTaskExternalId: string | undefined;
additionalMetadata?: string[] | undefined;
createdAfter?: string;
showQueueMetrics: boolean;
}) => {
const { tenantId } = useCurrentTenantId();
const { refetchInterval } = useRefetchInterval();
const metricsQuery = useQuery({
const {
data: rawStatusCounts,
isLoading: isStatusCountsLoading,
isFetching: isStatusCountsFetching,
isRefetching: isStatusCountsRefetching,
refetch,
} = useQuery({
...queries.v1TaskRuns.metrics(tenantId, {
since:
createdAfter ||
@@ -30,24 +38,23 @@ export const useMetrics = ({
refetchInterval,
});
const metrics = metricsQuery.data || [];
const runStatusCounts = rawStatusCounts || [];
const tenantMetricsQuery = useQuery({
const { data: queueMetricsRaw, isLoading: isQueueMetricsLoading } = useQuery({
...queries.metrics.getStepRunQueueMetrics(tenantId),
refetchInterval,
refetchInterval: 5000,
enabled: showQueueMetrics,
});
const tenantMetrics = tenantMetricsQuery.data?.queues || {};
const queueMetrics = queueMetricsRaw?.queues || {};
return {
isLoading: metricsQuery.isLoading || tenantMetricsQuery.isLoading,
isFetching: metricsQuery.isFetching || tenantMetricsQuery.isFetching,
isRefetching: metricsQuery.isRefetching || tenantMetricsQuery.isRefetching,
tenantMetrics,
metrics,
refetch: () => {
tenantMetricsQuery.refetch();
metricsQuery.refetch();
},
runStatusCounts,
isStatusCountsRefetching,
isStatusCountsLoading,
isStatusCountsFetching,
isQueueMetricsLoading,
refetch,
queueMetrics,
};
};