Alerting: Improve new list view performance (#108115)
This commit is contained in:
@@ -118,18 +118,20 @@ export const prometheusApi = alertingApi.injectEndpoints({
|
||||
export function usePopulateGrafanaPrometheusApiCache() {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const populateGroupResponseCache = useCallback(
|
||||
(group: GrafanaPromRuleGroupDTO) => {
|
||||
const populateGroupsResponseCache = useCallback(
|
||||
(groups: GrafanaPromRuleGroupDTO[]) => {
|
||||
dispatch(
|
||||
prometheusApi.util.upsertQueryData(
|
||||
'getGrafanaGroups',
|
||||
{ folderUid: group.folderUid, groupName: group.name },
|
||||
{ data: { groups: [group] }, status: 'success' }
|
||||
prometheusApi.util.upsertQueryEntries(
|
||||
groups.map((group) => ({
|
||||
endpointName: 'getGrafanaGroups',
|
||||
arg: { folderUid: group.folderUid, groupName: group.name, limitAlerts: 0 },
|
||||
value: { data: { groups: [group] }, status: 'success' },
|
||||
}))
|
||||
)
|
||||
);
|
||||
},
|
||||
[dispatch]
|
||||
);
|
||||
|
||||
return { populateGroupResponseCache };
|
||||
return { populateGroupsResponseCache };
|
||||
}
|
||||
|
||||
@@ -51,9 +51,7 @@ function PaginatedGroupsLoader({ rulesSourceIdentifier, application, groupFilter
|
||||
const hasFilters = Boolean(groupFilter || namespaceFilter);
|
||||
|
||||
const { uid, name } = rulesSourceIdentifier;
|
||||
const prometheusGroupsGenerator = usePrometheusGroupsGenerator({
|
||||
populateCache: hasFilters ? false : true,
|
||||
});
|
||||
const prometheusGroupsGenerator = usePrometheusGroupsGenerator();
|
||||
|
||||
// If there are no filters we can match one frontend page to one API page.
|
||||
// However, if there are filters, we need to fetch more groups from the API to populate one frontend page
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { useDispatch } from 'app/types/store';
|
||||
import { DataSourceRulesSourceIdentifier, RuleHealth } from 'app/types/unified-alerting';
|
||||
import { PromAlertingRuleState, PromRuleGroupDTO } from 'app/types/unified-alerting-dto';
|
||||
|
||||
import { PromRulesResponse, prometheusApi } from '../../api/prometheusApi';
|
||||
import { PromRulesResponse, prometheusApi, usePopulateGrafanaPrometheusApiCache } from '../../api/prometheusApi';
|
||||
|
||||
const { useLazyGetGroupsQuery, useLazyGetGrafanaGroupsQuery } = prometheusApi;
|
||||
|
||||
@@ -22,8 +21,7 @@ interface FetchGroupsOptions {
|
||||
groupNextToken?: string;
|
||||
}
|
||||
|
||||
export function usePrometheusGroupsGenerator(hookOptions: UseGeneratorHookOptions = {}) {
|
||||
const dispatch = useDispatch();
|
||||
export function usePrometheusGroupsGenerator() {
|
||||
const [getGroups] = useLazyGetGroupsQuery();
|
||||
|
||||
return useCallback(
|
||||
@@ -35,24 +33,12 @@ export function usePrometheusGroupsGenerator(hookOptions: UseGeneratorHookOption
|
||||
...fetchOptions,
|
||||
}).unwrap();
|
||||
|
||||
if (hookOptions.populateCache) {
|
||||
response.data.groups.forEach((group) => {
|
||||
dispatch(
|
||||
prometheusApi.util.upsertQueryData(
|
||||
'getGroups',
|
||||
{ ruleSource: { uid: ruleSource.uid }, namespace: group.file, groupName: group.name },
|
||||
{ data: { groups: [group] }, status: 'success' }
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
};
|
||||
|
||||
yield* genericGroupsGenerator(getRuleSourceGroupsWithCache, groupLimit);
|
||||
},
|
||||
[getGroups, dispatch, hookOptions.populateCache]
|
||||
[getGroups]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -67,8 +53,8 @@ interface GrafanaFetchGroupsOptions extends FetchGroupsOptions {
|
||||
}
|
||||
|
||||
export function useGrafanaGroupsGenerator(hookOptions: UseGeneratorHookOptions = {}) {
|
||||
const dispatch = useDispatch();
|
||||
const [getGrafanaGroups] = useLazyGetGrafanaGroupsQuery();
|
||||
const { populateGroupsResponseCache } = usePopulateGrafanaPrometheusApiCache();
|
||||
|
||||
const getGroupsAndProvideCache = useCallback(
|
||||
async (fetchOptions: GrafanaFetchGroupsOptions) => {
|
||||
@@ -78,25 +64,13 @@ export function useGrafanaGroupsGenerator(hookOptions: UseGeneratorHookOptions =
|
||||
...fetchOptions.filter,
|
||||
}).unwrap();
|
||||
|
||||
// This is not mandatory to preload ruler rules, but it improves the UX
|
||||
// Because the user waits a bit longer for the initial load but doesn't need to wait for each group to be loaded
|
||||
if (hookOptions.populateCache) {
|
||||
const cacheAndRulerPreload = response.data.groups.map(async (group) => {
|
||||
await dispatch(
|
||||
prometheusApi.util.upsertQueryData(
|
||||
'getGrafanaGroups',
|
||||
{ folderUid: group.folderUid, groupName: group.name, limitAlerts: hookOptions.limitAlerts },
|
||||
{ data: { groups: [group] }, status: 'success' }
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
await Promise.allSettled(cacheAndRulerPreload);
|
||||
populateGroupsResponseCache(response.data.groups);
|
||||
}
|
||||
|
||||
return response;
|
||||
},
|
||||
[getGrafanaGroups, dispatch, hookOptions.populateCache, hookOptions.limitAlerts]
|
||||
[getGrafanaGroups, hookOptions.limitAlerts, hookOptions.populateCache, populateGroupsResponseCache]
|
||||
);
|
||||
|
||||
return useCallback(
|
||||
|
||||
@@ -15,7 +15,6 @@ import {
|
||||
PromRuleGroupDTO,
|
||||
} from 'app/types/unified-alerting-dto';
|
||||
|
||||
import { usePopulateGrafanaPrometheusApiCache } from '../../api/prometheusApi';
|
||||
import { RulesFilter } from '../../search/rulesSearchParser';
|
||||
import {
|
||||
getDataSourceByUid,
|
||||
@@ -52,7 +51,6 @@ interface GetIteratorResult {
|
||||
}
|
||||
|
||||
export function useFilteredRulesIteratorProvider() {
|
||||
const { populateGroupResponseCache } = usePopulateGrafanaPrometheusApiCache();
|
||||
const allExternalRulesSources = getExternalRulesSources();
|
||||
|
||||
const prometheusGroupsGenerator = usePrometheusGroupsGenerator();
|
||||
@@ -76,10 +74,7 @@ export function useFilteredRulesIteratorProvider() {
|
||||
concatMap((groups) =>
|
||||
groups
|
||||
.filter((group) => groupFilter(group, normalizedFilterState))
|
||||
.flatMap((group) => {
|
||||
populateGroupResponseCache(group);
|
||||
return group.rules.map((rule) => [group, rule] as const);
|
||||
})
|
||||
.flatMap((group) => group.rules.map((rule) => [group, rule] as const))
|
||||
.filter(([, rule]) => ruleFilter(rule, normalizedFilterState))
|
||||
.map(([group, rule]) => mapGrafanaRuleToRuleWithOrigin(group, rule))
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user