diff --git a/static/app/views/explore/logs/constants.tsx b/static/app/views/explore/logs/constants.tsx index d50ee801f62515..cfb30eeb491760 100644 --- a/static/app/views/explore/logs/constants.tsx +++ b/static/app/views/explore/logs/constants.tsx @@ -20,6 +20,10 @@ export const LOG_ATTRIBUTE_LAZY_LOAD_HOVER_TIMEOUT = 150; export const DEFAULT_TRACE_ITEM_HOVER_TIMEOUT = 150; export const DEFAULT_TRACE_ITEM_HOVER_TIMEOUT_WITH_AUTO_REFRESH = 400; // With autorefresh on, a stationary mouse can prefetch multiple rows since virtual time moves rows constantly. export const MAX_LOGS_INFINITE_QUERY_PAGES = 30; // This number * the refresh interval must be more seconds than 2 * the smallest time interval in the chart for streaming to work. +/** Larger page cap once enough rows are cached (see useInfiniteLogsQuery). */ +export const MAX_LOGS_INFINITE_QUERY_PAGES_EXPANDED = 300; +/** Below this many rows in the client cache, use {@link MAX_LOGS_INFINITE_QUERY_PAGES}. */ +export const LOCAL_LOG_ROWS_FOR_EXPANDED_INFINITE_PAGES = 500; /** * These are required fields are always added to the query when fetching the log table. diff --git a/static/app/views/explore/logs/useLogsQuery.tsx b/static/app/views/explore/logs/useLogsQuery.tsx index 8c9614ef36857d..10a6530e069f6e 100644 --- a/static/app/views/explore/logs/useLogsQuery.tsx +++ b/static/app/views/explore/logs/useLogsQuery.tsx @@ -1,5 +1,6 @@ import {useCallback, useEffect, useMemo, useState} from 'react'; import {logger} from '@sentry/react'; +import type {QueryClient} from '@tanstack/react-query'; import {type ApiResult} from 'sentry/api'; import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters'; @@ -28,8 +29,10 @@ import {SAMPLING_MODE} from 'sentry/views/explore/hooks/useProgressiveQuery'; import {useTraceItemDetails} from 'sentry/views/explore/hooks/useTraceItemDetails'; import { AlwaysPresentLogFields, + LOCAL_LOG_ROWS_FOR_EXPANDED_INFINITE_PAGES, MAX_LOG_INGEST_DELAY, MAX_LOGS_INFINITE_QUERY_PAGES, + MAX_LOGS_INFINITE_QUERY_PAGES_EXPANDED, QUERY_PAGE_LIMIT, QUERY_PAGE_LIMIT_WITH_AUTO_REFRESH, } from 'sentry/views/explore/logs/constants'; @@ -402,6 +405,19 @@ type QueryKey = [ 'infinite', ]; +/** + * `maxPages` is evaluated before `useInfiniteQuery` returns `data`, so we base it on the + * query cache (same snapshot React Query will use for this key). + */ +function maxPagesForLogsInfiniteQuery(client: QueryClient, queryKey: QueryKey): number { + const cached = client.getQueryData>>(queryKey); + const rows = + cached?.pages?.reduce((n, page) => n + (page[0]?.data?.length ?? 0), 0) ?? 0; + return rows < LOCAL_LOG_ROWS_FOR_EXPANDED_INFINITE_PAGES + ? MAX_LOGS_INFINITE_QUERY_PAGES_EXPANDED + : MAX_LOGS_INFINITE_QUERY_PAGES; +} + export function useInfiniteLogsQuery({ disabled, highFidelity, @@ -526,7 +542,7 @@ export function useInfiniteLogsQuery({ initialPageParam, enabled: !disabled, staleTime: autoRefresh ? Infinity : getStaleTimeForEventView(other.eventView), - maxPages: MAX_LOGS_INFINITE_QUERY_PAGES, + maxPages: maxPagesForLogsInfiniteQuery(queryClient, queryKeyWithInfinite), refetchIntervalInBackground: true, // Don't refetch when tab is not visible });