vmui: optimize memory (#3255)

* fix: change series limit logic

* fix: remove spread operators
This commit is contained in:
Yury Molodov 2022-10-24 19:51:24 +02:00 committed by GitHub
parent 59199a98dd
commit 274e235bf7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 28 deletions

View file

@ -69,16 +69,13 @@ const GraphView: FC<GraphViewProps> = ({
const tempTimes: number[] = []; const tempTimes: number[] = [];
const tempValues: {[key: string]: number[]} = {}; const tempValues: {[key: string]: number[]} = {};
const tempLegend: LegendItem[] = []; const tempLegend: LegendItem[] = [];
const tempSeries: uPlotSeries[] = []; const tempSeries: uPlotSeries[] = [{}];
data?.forEach((d) => { data?.forEach((d) => {
const seriesItem = getSeriesItem(d, hideSeries, alias); const seriesItem = getSeriesItem(d, hideSeries, alias);
tempSeries.push(seriesItem); tempSeries.push(seriesItem);
tempLegend.push(getLegendItem(seriesItem, d.group)); tempLegend.push(getLegendItem(seriesItem, d.group));
let tmpValues = tempValues[d.group]; const tmpValues = tempValues[d.group] || [];
if (!tmpValues) {
tmpValues = [];
}
for (const v of d.values) { for (const v of d.values) {
tempTimes.push(v[0]); tempTimes.push(v[0]);
tmpValues.push(promValueToNumber(v[1])); tmpValues.push(promValueToNumber(v[1]));
@ -87,14 +84,15 @@ const GraphView: FC<GraphViewProps> = ({
}); });
const timeSeries = getTimeSeries(tempTimes, currentStep, period); const timeSeries = getTimeSeries(tempTimes, currentStep, period);
setDataChart([timeSeries, ...data.map(d => { const timeDataSeries = data.map(d => {
const results = []; const results = [];
const values = d.values; const values = d.values;
const length = values.length;
let j = 0; let j = 0;
for (const t of timeSeries) { for (const t of timeSeries) {
while (j < values.length && values[j][0] < t) j++; while (j < length && values[j][0] < t) j++;
let v = null; let v = null;
if (j < values.length && values[j][0] == t) { if (j < length && values[j][0] == t) {
v = promValueToNumber(values[j][1]); v = promValueToNumber(values[j][1]);
if (!Number.isFinite(v)) { if (!Number.isFinite(v)) {
// Treat special values as nulls in order to satisfy uPlot. // Treat special values as nulls in order to satisfy uPlot.
@ -105,25 +103,24 @@ const GraphView: FC<GraphViewProps> = ({
results.push(v); results.push(v);
} }
return results; return results;
})] as uPlotData); });
setLimitsYaxis(tempValues); timeDataSeries.unshift(timeSeries);
const newSeries = [{}, ...tempSeries]; setLimitsYaxis(tempValues);
if (JSON.stringify(newSeries) !== JSON.stringify(series)) { setDataChart(timeDataSeries as uPlotData);
setSeries(newSeries); setSeries(tempSeries);
setLegend(tempLegend); setLegend(tempLegend);
}
}, [data]); }, [data]);
useEffect(() => { useEffect(() => {
const tempLegend: LegendItem[] = []; const tempLegend: LegendItem[] = [];
const tempSeries: uPlotSeries[] = []; const tempSeries: uPlotSeries[] = [{}];
data?.forEach(d => { data?.forEach(d => {
const seriesItem = getSeriesItem(d, hideSeries, alias); const seriesItem = getSeriesItem(d, hideSeries, alias);
tempSeries.push(seriesItem); tempSeries.push(seriesItem);
tempLegend.push(getLegendItem(seriesItem, d.group)); tempLegend.push(getLegendItem(seriesItem, d.group));
}); });
setSeries([{}, ...tempSeries]); setSeries(tempSeries);
setLegend(tempLegend); setLegend(tempLegend);
}, [hideSeries]); }, [hideSeries]);

View file

@ -48,38 +48,43 @@ export const useFetchQuery = ({predefinedQuery, visible, display, customStep}: F
const fetchData = async (fetchUrl: string[], fetchQueue: AbortController[], displayType: DisplayType, query: string[]) => { const fetchData = async (fetchUrl: string[], fetchQueue: AbortController[], displayType: DisplayType, query: string[]) => {
const controller = new AbortController(); const controller = new AbortController();
setFetchQueue([...fetchQueue, controller]); setFetchQueue([...fetchQueue, controller]);
const isDisplayChart = displayType === "chart";
try { try {
const responses = await Promise.all(fetchUrl.map(url => fetch(url, {signal: controller.signal}))); const isDisplayChart = displayType === "chart";
const seriesLimit = MAX_SERIES[displayType];
const tempData: MetricBase[] = []; const tempData: MetricBase[] = [];
const tempTraces: Trace[] = []; const tempTraces: Trace[] = [];
let counter = 1; let counter = 1;
let totalLength = 0;
for await (const response of responses) { for await (const url of fetchUrl) {
const response = await fetch(url, {signal: controller.signal});
const resp = await response.json(); const resp = await response.json();
if (response.ok) { if (response.ok) {
setError(undefined); setError(undefined);
if (resp.trace) { if (resp.trace) {
const trace = new Trace(resp.trace, query[counter-1]); const trace = new Trace(resp.trace, query[counter - 1]);
tempTraces.push(trace); tempTraces.push(trace);
} }
resp.data.result.forEach((d: MetricBase) => {
const freeTempSize = seriesLimit - tempData.length;
resp.data.result.slice(0, freeTempSize).forEach((d: MetricBase) => {
d.group = counter; d.group = counter;
tempData.push(d); tempData.push(d);
}); });
totalLength += resp.data.result.length;
counter++; counter++;
} else { } else {
setError(`${resp.errorType}\r\n${resp?.error}`); setError(`${resp.errorType}\r\n${resp?.error}`);
} }
} }
const length = tempData.length; const limitText = `Showing ${seriesLimit} series out of ${totalLength} series due to performance reasons. Please narrow down the query, so it returns less series`;
const seriesLimit = MAX_SERIES[displayType]; setWarning(totalLength > seriesLimit ? limitText : "");
const result = tempData.slice(0, seriesLimit);
const limitText = `Showing ${seriesLimit} series out of ${length} series due to performance reasons. Please narrow down the query, so it returns less series`;
setWarning(length > seriesLimit ? limitText : "");
isDisplayChart ? setGraphData(result as MetricResult[]) : setLiveData(result as InstantMetricResult[]); isDisplayChart ? setGraphData(tempData as MetricResult[]) : setLiveData(tempData as InstantMetricResult[]);
setTraces(tempTraces); setTraces(tempTraces);
} catch (e) { } catch (e) {
if (e instanceof Error && e.name !== "AbortError") { if (e instanceof Error && e.name !== "AbortError") {