diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryField.test.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryField.test.tsx
index 07175ecd17b..cc715189263 100644
--- a/public/app/plugins/datasource/prometheus/components/PromQueryField.test.tsx
+++ b/public/app/plugins/datasource/prometheus/components/PromQueryField.test.tsx
@@ -94,6 +94,55 @@ describe('PromQueryField', () => {
checkMetricsInCascader(await screen.findByRole('button'), changedMetrics);
});
+ it('does not refreshes metrics when after rounding to minute time range does not change', async () => {
+ const defaultProps = {
+ query: { expr: '', refId: '' },
+ onRunQuery: () => {},
+ onChange: () => {},
+ history: [],
+ };
+ const metrics = ['foo', 'bar'];
+ const changedMetrics = ['foo', 'baz'];
+ const range = {
+ from: dateTime('2020-10-28T00:00:00Z'),
+ to: dateTime('2020-10-28T01:00:00Z'),
+ };
+
+ const languageProvider = makeLanguageProvider({ metrics: [metrics, changedMetrics] });
+ const queryField = render(
+
+ );
+ checkMetricsInCascader(await screen.findByRole('button'), metrics);
+
+ const newRange = {
+ from: dateTime('2020-10-28T00:00:01Z'),
+ to: dateTime('2020-10-28T01:00:01Z'),
+ };
+ queryField.rerender(
+
+ );
+ let cascader = screen.getByRole('button');
+ // Should not show loading
+ expect(cascader.textContent).toContain('Metrics');
+ checkMetricsInCascader(await screen.findByRole('button'), metrics);
+ });
+
it('refreshes metrics when time range changes but dont show loading state', async () => {
const defaultProps = {
query: { expr: '', refId: '' },
diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx
index 16ca7b0f20c..752c9ac0a12 100644
--- a/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx
+++ b/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx
@@ -16,8 +16,16 @@ import { LanguageMap, languages as prismLanguages } from 'prismjs';
// dom also includes Element polyfills
import { PromQuery, PromOptions, PromMetricsMetadata } from '../types';
+import { roundMsToMin } from '../language_utils';
import { CancelablePromise, makePromiseCancelable } from 'app/core/utils/CancelablePromise';
-import { ExploreQueryFieldProps, QueryHint, isDataFrame, toLegacyResponseData, HistoryItem } from '@grafana/data';
+import {
+ ExploreQueryFieldProps,
+ QueryHint,
+ isDataFrame,
+ toLegacyResponseData,
+ HistoryItem,
+ TimeRange,
+} from '@grafana/data';
import { DOMUtil, SuggestionsState } from '@grafana/ui';
import { PrometheusDatasource } from '../datasource';
@@ -168,17 +176,6 @@ class PromQueryField extends React.PureComponent {
let query;
if (selectedOptions.length === 1) {
diff --git a/public/app/plugins/datasource/prometheus/language_provider.ts b/public/app/plugins/datasource/prometheus/language_provider.ts
index 685517fe0df..e54a1835966 100644
--- a/public/app/plugins/datasource/prometheus/language_provider.ts
+++ b/public/app/plugins/datasource/prometheus/language_provider.ts
@@ -5,7 +5,13 @@ import { Value } from 'slate';
import { dateTime, HistoryItem, LanguageProvider } from '@grafana/data';
import { CompletionItem, CompletionItemGroup, TypeaheadInput, TypeaheadOutput } from '@grafana/ui';
-import { fixSummariesMetadata, parseSelector, processHistogramLabels, processLabels } from './language_utils';
+import {
+ fixSummariesMetadata,
+ parseSelector,
+ processHistogramLabels,
+ processLabels,
+ roundSecToMin,
+} from './language_utils';
import PromqlSyntax, { FUNCTIONS, RATE_RANGES } from './promql';
import { PrometheusDatasource } from './datasource';
@@ -421,10 +427,6 @@ export default class PromQlLanguageProvider extends LanguageProvider {
return { [key]: data };
};
- roundToMinutes(seconds: number): number {
- return Math.floor(seconds / 60);
- }
-
/**
* Fetch labels for a series. This is cached by it's args but also by the global timeRange currently selected as
* they can change over requested time.
@@ -443,8 +445,8 @@ export default class PromQlLanguageProvider extends LanguageProvider {
// The rounding may seem strange but makes relative intervals like now-1h less prone to need separate request every
// millisecond while still actually getting all the keys for the correct interval. This still can create problems
// when user does not the newest values for a minute if already cached.
- params.set('start', this.roundToMinutes(tRange['start']).toString());
- params.set('end', this.roundToMinutes(tRange['end']).toString());
+ params.set('start', roundSecToMin(tRange['start']).toString());
+ params.set('end', roundSecToMin(tRange['end']).toString());
params.append('withName', withName ? 'true' : 'false');
const cacheKey = `/api/v1/series?${params.toString()}`;
let value = this.labelsCache.get(cacheKey);
diff --git a/public/app/plugins/datasource/prometheus/language_utils.ts b/public/app/plugins/datasource/prometheus/language_utils.ts
index 716172a131f..13d56b7bc31 100644
--- a/public/app/plugins/datasource/prometheus/language_utils.ts
+++ b/public/app/plugins/datasource/prometheus/language_utils.ts
@@ -185,3 +185,11 @@ export function fixSummariesMetadata(metadata: PromMetricsMetadata): PromMetrics
}
return { ...metadata, ...summaryMetadata };
}
+
+export function roundMsToMin(milliseconds: number): number {
+ return roundSecToMin(milliseconds / 1000);
+}
+
+export function roundSecToMin(seconds: number): number {
+ return Math.floor(seconds / 60);
+}