|
@@ -22,6 +22,7 @@ import {
|
|
|
import { updateLocation } from 'app/core/actions';
|
|
import { updateLocation } from 'app/core/actions';
|
|
|
|
|
|
|
|
// Types
|
|
// Types
|
|
|
|
|
+import { ResultGetter } from 'app/types/explore';
|
|
|
import { ThunkResult } from 'app/types';
|
|
import { ThunkResult } from 'app/types';
|
|
|
import {
|
|
import {
|
|
|
RawTimeRange,
|
|
RawTimeRange,
|
|
@@ -44,6 +45,8 @@ import {
|
|
|
import {
|
|
import {
|
|
|
updateDatasourceInstanceAction,
|
|
updateDatasourceInstanceAction,
|
|
|
changeQueryAction,
|
|
changeQueryAction,
|
|
|
|
|
+ changeRefreshIntervalAction,
|
|
|
|
|
+ ChangeRefreshIntervalPayload,
|
|
|
changeSizeAction,
|
|
changeSizeAction,
|
|
|
ChangeSizePayload,
|
|
ChangeSizePayload,
|
|
|
changeTimeAction,
|
|
changeTimeAction,
|
|
@@ -164,7 +167,7 @@ export function changeSize(
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * Change the time range of Explore. Usually called from the Timepicker or a graph interaction.
|
|
|
|
|
|
|
+ * Change the time range of Explore. Usually called from the Time picker or a graph interaction.
|
|
|
*/
|
|
*/
|
|
|
export function changeTime(exploreId: ExploreId, range: TimeRange): ThunkResult<void> {
|
|
export function changeTime(exploreId: ExploreId, range: TimeRange): ThunkResult<void> {
|
|
|
return dispatch => {
|
|
return dispatch => {
|
|
@@ -173,6 +176,16 @@ export function changeTime(exploreId: ExploreId, range: TimeRange): ThunkResult<
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * Change the refresh interval of Explore. Called from the Refresh picker.
|
|
|
|
|
+ */
|
|
|
|
|
+export function changeRefreshInterval(
|
|
|
|
|
+ exploreId: ExploreId,
|
|
|
|
|
+ refreshInterval: string
|
|
|
|
|
+): ActionOf<ChangeRefreshIntervalPayload> {
|
|
|
|
|
+ return changeRefreshIntervalAction({ exploreId, refreshInterval });
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* Clear all queries and results.
|
|
* Clear all queries and results.
|
|
|
*/
|
|
*/
|
|
@@ -526,7 +539,7 @@ export function queryTransactionSuccess(
|
|
|
/**
|
|
/**
|
|
|
* Main action to run queries and dispatches sub-actions based on which result viewers are active
|
|
* Main action to run queries and dispatches sub-actions based on which result viewers are active
|
|
|
*/
|
|
*/
|
|
|
-export function runQueries(exploreId: ExploreId, ignoreUIState = false): ThunkResult<void> {
|
|
|
|
|
|
|
+export function runQueries(exploreId: ExploreId, ignoreUIState = false): ThunkResult<Promise<any>> {
|
|
|
return (dispatch, getState) => {
|
|
return (dispatch, getState) => {
|
|
|
const {
|
|
const {
|
|
|
datasourceInstance,
|
|
datasourceInstance,
|
|
@@ -543,13 +556,13 @@ export function runQueries(exploreId: ExploreId, ignoreUIState = false): ThunkRe
|
|
|
|
|
|
|
|
if (datasourceError) {
|
|
if (datasourceError) {
|
|
|
// let's not run any queries if data source is in a faulty state
|
|
// let's not run any queries if data source is in a faulty state
|
|
|
- return;
|
|
|
|
|
|
|
+ return Promise.resolve();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (!hasNonEmptyQuery(queries)) {
|
|
if (!hasNonEmptyQuery(queries)) {
|
|
|
dispatch(clearQueriesAction({ exploreId }));
|
|
dispatch(clearQueriesAction({ exploreId }));
|
|
|
dispatch(stateSave()); // Remember to saves to state and update location
|
|
dispatch(stateSave()); // Remember to saves to state and update location
|
|
|
- return;
|
|
|
|
|
|
|
+ return Promise.resolve();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Some datasource's query builders allow per-query interval limits,
|
|
// Some datasource's query builders allow per-query interval limits,
|
|
@@ -558,41 +571,46 @@ export function runQueries(exploreId: ExploreId, ignoreUIState = false): ThunkRe
|
|
|
|
|
|
|
|
dispatch(runQueriesAction({ exploreId }));
|
|
dispatch(runQueriesAction({ exploreId }));
|
|
|
// Keep table queries first since they need to return quickly
|
|
// Keep table queries first since they need to return quickly
|
|
|
- if ((ignoreUIState || showingTable) && supportsTable) {
|
|
|
|
|
- dispatch(
|
|
|
|
|
- runQueriesForType(
|
|
|
|
|
- exploreId,
|
|
|
|
|
- 'Table',
|
|
|
|
|
- {
|
|
|
|
|
- interval,
|
|
|
|
|
- format: 'table',
|
|
|
|
|
- instant: true,
|
|
|
|
|
- valueWithRefId: true,
|
|
|
|
|
- },
|
|
|
|
|
- (data: any) => data[0]
|
|
|
|
|
- )
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
- if ((ignoreUIState || showingGraph) && supportsGraph) {
|
|
|
|
|
- dispatch(
|
|
|
|
|
- runQueriesForType(
|
|
|
|
|
- exploreId,
|
|
|
|
|
- 'Graph',
|
|
|
|
|
- {
|
|
|
|
|
- interval,
|
|
|
|
|
- format: 'time_series',
|
|
|
|
|
- instant: false,
|
|
|
|
|
- maxDataPoints: containerWidth,
|
|
|
|
|
- },
|
|
|
|
|
- makeTimeSeriesList
|
|
|
|
|
- )
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
- if ((ignoreUIState || showingLogs) && supportsLogs) {
|
|
|
|
|
- dispatch(runQueriesForType(exploreId, 'Logs', { interval, format: 'logs' }));
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const tableQueriesPromise =
|
|
|
|
|
+ (ignoreUIState || showingTable) && supportsTable
|
|
|
|
|
+ ? dispatch(
|
|
|
|
|
+ runQueriesForType(
|
|
|
|
|
+ exploreId,
|
|
|
|
|
+ 'Table',
|
|
|
|
|
+ {
|
|
|
|
|
+ interval,
|
|
|
|
|
+ format: 'table',
|
|
|
|
|
+ instant: true,
|
|
|
|
|
+ valueWithRefId: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ (data: any[]) => data[0]
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+ : undefined;
|
|
|
|
|
+ const typeQueriesPromise =
|
|
|
|
|
+ (ignoreUIState || showingGraph) && supportsGraph
|
|
|
|
|
+ ? dispatch(
|
|
|
|
|
+ runQueriesForType(
|
|
|
|
|
+ exploreId,
|
|
|
|
|
+ 'Graph',
|
|
|
|
|
+ {
|
|
|
|
|
+ interval,
|
|
|
|
|
+ format: 'time_series',
|
|
|
|
|
+ instant: false,
|
|
|
|
|
+ maxDataPoints: containerWidth,
|
|
|
|
|
+ },
|
|
|
|
|
+ makeTimeSeriesList
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+ : undefined;
|
|
|
|
|
+ const logsQueriesPromise =
|
|
|
|
|
+ (ignoreUIState || showingLogs) && supportsLogs
|
|
|
|
|
+ ? dispatch(runQueriesForType(exploreId, 'Logs', { interval, format: 'logs' }))
|
|
|
|
|
+ : undefined;
|
|
|
|
|
|
|
|
dispatch(stateSave());
|
|
dispatch(stateSave());
|
|
|
|
|
+
|
|
|
|
|
+ return Promise.all([tableQueriesPromise, typeQueriesPromise, logsQueriesPromise]);
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -607,14 +625,13 @@ function runQueriesForType(
|
|
|
exploreId: ExploreId,
|
|
exploreId: ExploreId,
|
|
|
resultType: ResultType,
|
|
resultType: ResultType,
|
|
|
queryOptions: QueryOptions,
|
|
queryOptions: QueryOptions,
|
|
|
- resultGetter?: any
|
|
|
|
|
|
|
+ resultGetter?: ResultGetter
|
|
|
): ThunkResult<void> {
|
|
): ThunkResult<void> {
|
|
|
return async (dispatch, getState) => {
|
|
return async (dispatch, getState) => {
|
|
|
const { datasourceInstance, eventBridge, queries, queryIntervals, range, scanning } = getState().explore[exploreId];
|
|
const { datasourceInstance, eventBridge, queries, queryIntervals, range, scanning } = getState().explore[exploreId];
|
|
|
const datasourceId = datasourceInstance.meta.id;
|
|
const datasourceId = datasourceInstance.meta.id;
|
|
|
-
|
|
|
|
|
// Run all queries concurrently
|
|
// Run all queries concurrently
|
|
|
- queries.forEach(async (query, rowIndex) => {
|
|
|
|
|
|
|
+ const queryPromises = queries.map(async (query, rowIndex) => {
|
|
|
const transaction = buildQueryTransaction(
|
|
const transaction = buildQueryTransaction(
|
|
|
query,
|
|
query,
|
|
|
rowIndex,
|
|
rowIndex,
|
|
@@ -638,6 +655,8 @@ function runQueriesForType(
|
|
|
dispatch(queryTransactionFailure(exploreId, transaction.id, response, datasourceId));
|
|
dispatch(queryTransactionFailure(exploreId, transaction.id, response, datasourceId));
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
+
|
|
|
|
|
+ return Promise.all(queryPromises);
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -814,7 +833,6 @@ export function refreshExplore(exploreId: ExploreId): ThunkResult<void> {
|
|
|
const { datasource, queries, range, ui } = urlState;
|
|
const { datasource, queries, range, ui } = urlState;
|
|
|
const refreshQueries = queries.map(q => ({ ...q, ...generateEmptyQuery(itemState.queries) }));
|
|
const refreshQueries = queries.map(q => ({ ...q, ...generateEmptyQuery(itemState.queries) }));
|
|
|
const refreshRange = { from: parseTime(range.from), to: parseTime(range.to) };
|
|
const refreshRange = { from: parseTime(range.from), to: parseTime(range.to) };
|
|
|
-
|
|
|
|
|
// need to refresh datasource
|
|
// need to refresh datasource
|
|
|
if (update.datasource) {
|
|
if (update.datasource) {
|
|
|
const initialQueries = ensureQueries(queries);
|
|
const initialQueries = ensureQueries(queries);
|