Prometheus: Cancellable label values requests (#86403)

* feat: cancellable label values requests

* refactor: prefer more explicit `requestId`

* refactor: request options to avoid tedious test changes

* refactor: avoid `any`
This commit is contained in:
Nick Richmond 2024-04-17 15:03:31 -04:00 committed by GitHub
parent 15ff166fb6
commit 00256d3fdd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 20 deletions

View File

@ -729,12 +729,13 @@ export class PrometheusDatasource
const expr = promQueryModeller.renderLabels(labelFilters);
if (this.hasLabelsMatchAPISupport()) {
return (await this.languageProvider.fetchSeriesValuesWithMatch(options.key, expr, options.timeRange)).map(
(v) => ({
value: v,
text: v,
})
);
const requestId = `[${this.uid}][${options.key}]`;
return (
await this.languageProvider.fetchSeriesValuesWithMatch(options.key, expr, requestId, options.timeRange)
).map((v) => ({
value: v,
text: v,
}));
}
const params = this.getTimeRangeParams(options.timeRange ?? getDefaultTimeRange());

View File

@ -108,7 +108,9 @@ export default class PromQlLanguageProvider extends LanguageProvider {
const res = await this.datasource.metadataRequest(url, params, options);
return res.data.data;
} catch (error) {
console.error(error);
if (!isCancelledError(error)) {
console.error(error);
}
}
return defaultValue;
@ -257,10 +259,12 @@ export default class PromQlLanguageProvider extends LanguageProvider {
* @param name
* @param match
* @param timeRange
* @param requestId
*/
fetchSeriesValuesWithMatch = async (
name: string,
match?: string,
match: string,
requestId?: string,
timeRange: TimeRange = this.timeRange
): Promise<string[]> => {
const interpolatedName = name ? this.datasource.interpolateString(name) : null;
@ -270,13 +274,16 @@ export default class PromQlLanguageProvider extends LanguageProvider {
...range,
...(interpolatedMatch && { 'match[]': interpolatedMatch }),
};
let requestOptions: Partial<BackendSrvRequest> | undefined = {
...this.getDefaultCacheHeaders(),
...(requestId && { requestId }),
};
const value = await this.request(
`/api/v1/label/${interpolatedName}/values`,
[],
urlParams,
this.getDefaultCacheHeaders()
);
if (!Object.keys(requestOptions).length) {
requestOptions = undefined;
}
const value = await this.request(`/api/v1/label/${interpolatedName}/values`, [], urlParams, requestOptions);
return value ?? [];
};
@ -393,3 +400,9 @@ function getNameLabelValue(promQuery: string, tokens: Array<string | Prism.Token
}
return nameLabelValue;
}
function isCancelledError(error: unknown): error is {
cancelled: boolean;
} {
return typeof error === 'object' && error !== null && 'cancelled' in error && error.cancelled === true;
}

View File

@ -148,12 +148,12 @@ export function MetricsLabelsSection({
if (!forLabel.label) {
return Promise.resolve([]);
}
return datasource.languageProvider.fetchSeriesValuesWithMatch(forLabel.label, promQLExpression).then((response) => {
return response.map((v) => ({
value: v,
label: v,
}));
});
const requestId = `[${datasource.uid}][${query.metric}][${forLabel.label}][${forLabel.op}]`;
return datasource.languageProvider
.fetchSeriesValuesWithMatch(forLabel.label, promQLExpression, requestId)
.then((response) => response.map((v) => ({ value: v, label: v })));
};
/**