Skip to content

Commit 9df9278

Browse files
committed
COO-1689: fix: prevent repeated reload of fetch useEffect
Reduce dependencies of useEffect, use a Ref for the result.
1 parent f53c4a5 commit 9df9278

2 files changed

Lines changed: 43 additions & 51 deletions

File tree

web/locales/en/plugin__troubleshooting-panel-console-plugin.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,23 @@
2020
"From": "From",
2121
"Goals": "Goals",
2222
"Include data from this time range": "Include data from this time range",
23-
"Korrel8r Error": "Korrel8r Error",
2423
"Last": "Last",
2524
"Logging Plugin Disabled": "Logging Plugin Disabled",
2625
"Neighbours": "Neighbours",
2726
"Neighbours or Goal search": "Neighbours or Goal search",
2827
"Netflow Plugin Disabled": "Netflow Plugin Disabled",
29-
"No correlated data was found": "No correlated data was found",
28+
"No correlated data found": "No correlated data found",
3029
"No Correlated Signals Found": "No Correlated Signals Found",
3130
"No starting point for correlation": "No starting point for correlation",
3231
"Open the Troubleshooting Panel": "Open the Troubleshooting Panel",
3332
"Other duration": "Other duration",
3433
"Quickly diagnose and resolve issues by exploring correlated observability signals for resources.": "Quickly diagnose and resolve issues by exploring correlated observability signals for resources.",
3534
"Refresh": "Refresh",
3635
"Refresh the graph by re-running the current search.": "Refresh the graph by re-running the current search.",
37-
"Request Failed": "Request Failed",
3836
"Save": "Save",
3937
"Search": "Search",
38+
"Search Error": "Search Error",
39+
"Search Failed": "Search Failed",
4040
"Search Type": "Search Type",
4141
"Searching": "Searching",
4242
"Select starting data": "Select starting data",

web/src/components/Korrel8rPanel.tsx

Lines changed: 40 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -55,43 +55,40 @@ export default function Korrel8rPanel() {
5555
// Showing advanced query
5656
const [showAdvanced, setShowAdvanced] = React.useState(false);
5757

58-
// Compute constraint from period for the API call and topology navigation.
58+
// Compute constraint from search period.
5959
const constraint = React.useMemo((): korrel8r.Constraint | undefined => {
6060
if (!search.period) return undefined;
61-
const [pStart, pEnd] = search.period.startEnd();
62-
return new korrel8r.Constraint({ start: pStart, end: pEnd });
63-
}, [search.period]);
61+
const [start, end] = search.period.startEnd();
62+
return new korrel8r.Constraint({ start, end });
63+
}, [search?.period]);
6464

65-
// Call korrel8r service to get results for the current search.
66-
React.useEffect(() => {
67-
// If we already have a stored result, do nothing.
68-
// Dispatching SetSearch sets result=null, triggering a new fetch.
69-
if (result) return;
70-
71-
let cancelled = false;
72-
const onResult = (newResult: Result) => {
73-
if (!cancelled) dispatch(setResult(newResult));
74-
};
65+
// Dispatch a new search value, making a new reference (reducer clears result automatically).
66+
const dispatchSearch = React.useCallback(
67+
(search: Search) => dispatch(setSearch({ ...search })),
68+
[dispatch],
69+
);
70+
// Dispatch a new result, no special actions.
71+
const dispatchResult = React.useCallback(
72+
(result: Result) => dispatch(setResult(result)),
73+
[dispatch],
74+
);
7575

76-
const queryStr = (search?.queryStr ?? '').trim();
76+
// Set up default locationQuery search on mount, when query is blank.
77+
React.useEffect(() => {
78+
if (!search?.queryStr && locationQuery?.toString())
79+
dispatchSearch({ ...defaultSearch, queryStr: locationQuery.toString() });
80+
}, [locationQuery, dispatchSearch, search?.queryStr]);
7781

82+
// Fetch a new result from the korrel8r service when the search changes.
83+
React.useEffect(() => {
84+
const queryStr = search?.queryStr;
7885
if (!queryStr) {
79-
// Default query or empty result
80-
if (locationQuery?.toString()) {
81-
dispatch(setSearch({ ...defaultSearch, queryStr: locationQuery?.toString() }));
82-
} else {
83-
dispatch(
84-
setResult({
85-
title: t('Empty Query'),
86-
message: t('No starting point for correlation'),
87-
}),
88-
);
89-
}
86+
dispatchResult({ title: t('Empty Query'), message: t('No starting point for correlation') });
9087
return;
9188
}
92-
89+
let cancelled = false;
9390
const start: api.Start = {
94-
queries: queryStr ? [queryStr] : undefined,
91+
queries: [queryStr],
9592
constraint: constraint?.toAPI(),
9693
};
9794

@@ -101,18 +98,17 @@ export default function Korrel8rPanel() {
10198
: getNeighborsGraph({ start, depth: search.depth });
10299
fetch
103100
.then((response: api.Graph) => {
104-
if (Array.isArray(response?.nodes) && response.nodes.length > 0) {
105-
onResult({ graph: new korrel8r.Graph(response) });
106-
} else {
107-
onResult({
108-
title: t('Empty Result'),
109-
message: t('No correlated data was found'),
110-
});
111-
}
101+
if (cancelled) return;
102+
dispatchResult(
103+
Array.isArray(response?.nodes) && response.nodes.length > 0
104+
? { graph: new korrel8r.Graph(response) }
105+
: { title: t('Empty Result'), message: t('No correlated data found') },
106+
);
112107
})
113108
.catch((e: api.ApiError) => {
114-
onResult({
115-
title: e?.body?.error ? t('Korrel8r Error') : t('Request Failed'),
109+
if (cancelled) return;
110+
dispatchResult({
111+
title: e?.body?.error ? t('Search Error') : t('Search Failed'),
116112
message: e?.body?.error || e.message || 'Unknown Error',
117113
isError: true,
118114
});
@@ -121,22 +117,18 @@ export default function Korrel8rPanel() {
121117
cancelled = true;
122118
fetch.cancel();
123119
};
124-
}, [search, t, result, constraint, dispatch, locationQuery]);
120+
}, [search, constraint, dispatchResult, t]);
125121

126122
const advancedToggleID = 'query-toggle';
127123
const advancedContentID = 'query-content';
128124

129-
// Dispatch a new search.
130-
// The SetSearch reducer clears result, triggering the fetch effect.
131-
const doSearch = React.useCallback((s: Search) => dispatch(setSearch(s)), [dispatch]);
132-
133125
return (
134126
<>
135127
<Stack>
136128
<Flex
137129
className="tp-plugin__panel-toolbar"
138130
direction={{ default: 'row' }}
139-
flexWrap={{ default: 'nowrap' }}
131+
flexWrap={{ default: 'wrap' }}
140132
alignItems={{ default: 'alignItemsCenter' }}
141133
spaceItems={{ default: 'spaceItemsXs' }}
142134
>
@@ -154,7 +146,7 @@ export default function Korrel8rPanel() {
154146
isAriaDisabled={!locationQuery || isFocused}
155147
size="sm"
156148
onClick={() => {
157-
doSearch({
149+
dispatchSearch({
158150
...defaultSearch,
159151
queryStr: locationQuery?.toString(),
160152
period: search?.period,
@@ -172,7 +164,7 @@ export default function Korrel8rPanel() {
172164
<TimeRangeDropdown
173165
className="tp-plugin__compact-control"
174166
period={search.period ?? defaultSearch.period}
175-
onChange={(period: time.Period) => doSearch({ ...search, period })}
167+
onChange={(period: time.Period) => dispatchSearch({ ...search, period })}
176168
/>
177169
</Tooltip>
178170
</Flex>
@@ -198,7 +190,7 @@ export default function Korrel8rPanel() {
198190
variant="link"
199191
size="sm"
200192
isAriaDisabled={!search?.queryStr}
201-
onClick={() => doSearch(search)}
193+
onClick={() => dispatchSearch(search)}
202194
aria-label={t('Refresh')}
203195
>
204196
<SyncIcon />
@@ -216,7 +208,7 @@ export default function Korrel8rPanel() {
216208
>
217209
<AdvancedSearchForm
218210
search={search}
219-
onSearch={doSearch}
211+
onSearch={dispatchSearch}
220212
onCancel={() => setShowAdvanced(false)}
221213
/>
222214
</ExpandableSection>

0 commit comments

Comments
 (0)