diff --git a/plugin-system/src/runtime/log-queries.ts b/plugin-system/src/runtime/log-queries.ts index 711b08f..d1bf6c0 100644 --- a/plugin-system/src/runtime/log-queries.ts +++ b/plugin-system/src/runtime/log-queries.ts @@ -18,6 +18,7 @@ import { useDatasourceStore } from './datasources'; import { usePluginRegistry } from './plugin-registry'; import { useTimeRange } from './TimeRangeProvider'; import { useVariableValues } from './variables'; +import { jitterDelay } from './utils'; export type LogQueryDefinition = QueryDefinition<'LogQuery', PluginSpec>; export const LOG_QUERY_KEY = 'LogQuery'; @@ -46,6 +47,7 @@ export function useLogQueries(definitions: LogQueryDefinition[]): Array => { + await jitterDelay(); const plugin = await getPlugin(LOG_QUERY_KEY, logQueryKind); const data = await plugin.getLogData(definition.spec.plugin.spec, context, signal); return data; diff --git a/plugin-system/src/runtime/profile-queries.ts b/plugin-system/src/runtime/profile-queries.ts index f677195..6fd2728 100644 --- a/plugin-system/src/runtime/profile-queries.ts +++ b/plugin-system/src/runtime/profile-queries.ts @@ -16,6 +16,7 @@ import { useQueries, UseQueryResult } from '@tanstack/react-query'; import { useDatasourceStore } from './datasources'; import { usePluginRegistry } from './plugin-registry'; import { useTimeRange } from './TimeRangeProvider'; +import { jitterDelay } from './utils'; export type ProfileQueryDefinition = QueryDefinition<'ProfileQuery', PluginSpec>; export const PROFILE_QUERY_KEY = 'ProfileQuery'; @@ -46,6 +47,7 @@ export function useProfileQueries(definitions: ProfileQueryDefinition[]): Array< refetchOnReconnect: false, staleTime: Infinity, queryFn: async ({ signal }: { signal?: AbortSignal }): Promise => { + await jitterDelay(); const plugin = await getPlugin(PROFILE_QUERY_KEY, profileQueryKind); const data = await plugin.getProfileData(definition.spec.plugin.spec, context, signal); return data; diff --git a/plugin-system/src/runtime/time-series-queries.ts b/plugin-system/src/runtime/time-series-queries.ts index 3c24068..4f7205b 100644 --- a/plugin-system/src/runtime/time-series-queries.ts +++ b/plugin-system/src/runtime/time-series-queries.ts @@ -26,7 +26,7 @@ import { TimeSeriesDataQuery, TimeSeriesQueryContext, TimeSeriesQueryMode, TimeS import { useTimeRange } from './TimeRangeProvider'; import { useDatasourceStore } from './datasources'; import { usePlugin, usePluginRegistry, usePlugins } from './plugin-registry'; -import { filterVariableStateMap, getVariableValuesKey } from './utils'; +import { filterVariableStateMap, getVariableValuesKey, jitterDelay } from './utils'; import { useAllVariableValues } from './variables'; export interface UseTimeSeriesQueryOptions { @@ -139,6 +139,7 @@ export function useTimeSeriesQueries( staleTime: Infinity, queryKey: queryKey, queryFn: async ({ signal }: { signal: AbortSignal }): Promise => { + await jitterDelay(); const plugin = await getPlugin(TIME_SERIES_QUERY_KEY, definition.spec.plugin.kind); const data = await plugin.getTimeSeriesData(definition.spec.plugin.spec, context, signal); return data; diff --git a/plugin-system/src/runtime/trace-queries.ts b/plugin-system/src/runtime/trace-queries.ts index f0d9ddb..259eabb 100644 --- a/plugin-system/src/runtime/trace-queries.ts +++ b/plugin-system/src/runtime/trace-queries.ts @@ -18,7 +18,7 @@ import { useDatasourceStore } from './datasources'; import { usePluginRegistry, usePlugins } from './plugin-registry'; import { useTimeRange } from './TimeRangeProvider'; import { useAllVariableValues } from './variables'; -import { filterVariableStateMap, getVariableValuesKey } from './utils'; +import { filterVariableStateMap, getVariableValuesKey, jitterDelay } from './utils'; export type TraceQueryDefinition = QueryDefinition<'TraceQuery', PluginSpec>; export const TRACE_QUERY_KEY = 'TraceQuery'; @@ -51,6 +51,7 @@ export function useTraceQueries(definitions: TraceQueryDefinition[]): Array => { + await jitterDelay(); const plugin = await getPlugin(TRACE_QUERY_KEY, traceQueryKind); const data = await plugin.getTraceData(definition.spec.plugin.spec, context, signal); return data; diff --git a/plugin-system/src/runtime/utils.ts b/plugin-system/src/runtime/utils.ts index 196e468..f93cdbe 100644 --- a/plugin-system/src/runtime/utils.ts +++ b/plugin-system/src/runtime/utils.ts @@ -28,3 +28,21 @@ export function getVariableValuesKey(v: VariableStateMap): string { .map((v) => JSON.stringify(v.value)) .join(','); } + +/** + * Adds a random jitter delay to distribute query requests over time. + * This helps reduce server load by preventing all panels from firing queries in bursts. + */ +export function jitterDelay(minMs = 0, maxMs = 500): Promise { + const safeMin = Number.isFinite(minMs) ? minMs : 0; + const safeMax = Number.isFinite(maxMs) ? maxMs : 0; + const normalizedMin = Math.max(0, Math.min(safeMin, safeMax)); + const normalizedMax = Math.max(0, Math.max(safeMin, safeMax)); + + if (normalizedMax === 0) { + return Promise.resolve(); + } + + const delay = Math.floor(Math.random() * (normalizedMax - normalizedMin + 1)) + normalizedMin; + return new Promise((resolve) => setTimeout(resolve, delay)); +}