From a04b3a13e05eecc7be7ed4d19dc77f70de90a651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Thu, 9 May 2019 12:24:48 +0200 Subject: [PATCH] Explore: Removes Promise.All from runQueries thunk (#16957) --- .../components/SetInterval/SetInterval.tsx | 55 ++++++------ .../app/features/explore/ExploreToolbar.tsx | 2 +- public/app/features/explore/state/actions.ts | 84 +++++++++---------- 3 files changed, 68 insertions(+), 73 deletions(-) diff --git a/packages/grafana-ui/src/components/SetInterval/SetInterval.tsx b/packages/grafana-ui/src/components/SetInterval/SetInterval.tsx index 37afe2c62d8..b44a49f9603 100644 --- a/packages/grafana-ui/src/components/SetInterval/SetInterval.tsx +++ b/packages/grafana-ui/src/components/SetInterval/SetInterval.tsx @@ -1,47 +1,48 @@ import { PureComponent } from 'react'; +import { interval, Subscription, empty, Subject } from 'rxjs'; +import { tap, switchMap } from 'rxjs/operators'; + import { stringToMs } from '../../utils/string'; interface Props { func: () => any; // TODO + loading: boolean; interval: string; } export class SetInterval extends PureComponent { - private intervalId = 0; + private propsSubject: Subject; + private subscription: Subscription | null; - componentDidMount() { - this.addInterval(); + constructor(props: Props) { + super(props); + this.propsSubject = new Subject(); + this.subscription = null; } - componentDidUpdate(prevProps: Props) { - const { interval } = this.props; - if (interval !== prevProps.interval) { - this.clearInterval(); - this.addInterval(); - } + componentDidMount() { + this.subscription = this.propsSubject + .pipe( + switchMap(props => { + return props.loading ? empty() : interval(stringToMs(props.interval)); + }), + tap(() => this.props.func()) + ) + .subscribe(); + this.propsSubject.next(this.props); + } + + componentDidUpdate() { + this.propsSubject.next(this.props); } componentWillUnmount() { - this.clearInterval(); - } - - addInterval = () => { - const { func, interval } = this.props; - - if (interval) { - func().then(() => { - if (interval) { - this.intervalId = window.setTimeout(() => { - this.addInterval(); - }, stringToMs(interval)); - } - }); + if (this.subscription) { + this.subscription.unsubscribe(); } - }; - clearInterval = () => { - window.clearTimeout(this.intervalId); - }; + this.propsSubject.unsubscribe(); + } render() { return null; diff --git a/public/app/features/explore/ExploreToolbar.tsx b/public/app/features/explore/ExploreToolbar.tsx index 8a9ae5c3057..d4f24b08455 100644 --- a/public/app/features/explore/ExploreToolbar.tsx +++ b/public/app/features/explore/ExploreToolbar.tsx @@ -171,7 +171,7 @@ export class UnConnectedExploreToolbar extends PureComponent { value={refreshInterval} tooltip="Refresh" /> - {refreshInterval && } + {refreshInterval && }
diff --git a/public/app/features/explore/state/actions.ts b/public/app/features/explore/state/actions.ts index 4e8c25b15bd..ebf269c4c08 100644 --- a/public/app/features/explore/state/actions.ts +++ b/public/app/features/explore/state/actions.ts @@ -546,7 +546,7 @@ export function queryTransactionSuccess( /** * Main action to run queries and dispatches sub-actions based on which result viewers are active */ -export function runQueries(exploreId: ExploreId, ignoreUIState = false): ThunkResult> { +export function runQueries(exploreId: ExploreId, ignoreUIState = false): ThunkResult { return (dispatch, getState) => { const { datasourceInstance, @@ -563,13 +563,13 @@ export function runQueries(exploreId: ExploreId, ignoreUIState = false): ThunkRe if (datasourceError) { // let's not run any queries if data source is in a faulty state - return Promise.resolve(); + return; } if (!hasNonEmptyQuery(queries)) { dispatch(clearQueriesAction({ exploreId })); dispatch(stateSave()); // Remember to saves to state and update location - return Promise.resolve(); + return; } // Some datasource's query builders allow per-query interval limits, @@ -578,46 +578,41 @@ export function runQueries(exploreId: ExploreId, ignoreUIState = false): ThunkRe dispatch(runQueriesAction({ exploreId })); // Keep table queries first since they need to return quickly - 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; + 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' })); + } dispatch(stateSave()); - - return Promise.all([tableQueriesPromise, typeQueriesPromise, logsQueriesPromise]); }; } @@ -638,7 +633,8 @@ function runQueriesForType( const { datasourceInstance, eventBridge, queries, queryIntervals, range, scanning } = getState().explore[exploreId]; const datasourceId = datasourceInstance.meta.id; // Run all queries concurrently - const queryPromises = queries.map(async (query, rowIndex) => { + for (let rowIndex = 0; rowIndex < queries.length; rowIndex++) { + const query = queries[rowIndex]; const transaction = buildQueryTransaction( query, rowIndex, @@ -661,9 +657,7 @@ function runQueriesForType( eventBridge.emit('data-error', response); dispatch(queryTransactionFailure(exploreId, transaction.id, response, datasourceId)); } - }); - - return Promise.all(queryPromises); + } }; }