Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explore: Use PanelQueryState to handle querying #18694

Merged
merged 12 commits into from Aug 28, 2019
1 change: 0 additions & 1 deletion package.json
Expand Up @@ -230,7 +230,6 @@
"react-window": "1.7.1",
"redux": "4.0.1",
"redux-logger": "3.0.6",
"redux-observable": "1.1.0",
"redux-thunk": "2.3.0",
"reselect": "4.0.0",
"rst2html": "github:thoward/rst2html#990cb89",
Expand Down
35 changes: 21 additions & 14 deletions public/app/core/utils/explore.ts
Expand Up @@ -2,14 +2,23 @@
import _ from 'lodash';
import { from } from 'rxjs';
import { isLive } from '@grafana/ui/src/components/RefreshPicker/RefreshPicker';

// Services & Utils
import { dateMath } from '@grafana/data';
import {
dateMath,
toUtc,
TimeRange,
RawTimeRange,
TimeZone,
IntervalValues,
TimeFragment,
LogRowModel,
LogsModel,
LogsDedupStrategy,
} from '@grafana/data';
import { renderUrl } from 'app/core/utils/url';
import kbn from 'app/core/utils/kbn';
import store from 'app/core/store';
import { getNextRefIdChar } from './query';

// Types
import {
DataQuery,
Expand All @@ -19,17 +28,6 @@ import {
DataQueryRequest,
DataStreamObserver,
} from '@grafana/ui';
import {
toUtc,
TimeRange,
RawTimeRange,
TimeZone,
IntervalValues,
TimeFragment,
LogRowModel,
LogsModel,
LogsDedupStrategy,
} from '@grafana/data';
import {
ExploreUrlState,
HistoryItem,
Expand All @@ -39,6 +37,7 @@ import {
ExploreMode,
} from 'app/types/explore';
import { config } from '../config';
import { PanelQueryState } from '../../features/dashboard/state/PanelQueryState';

export const DEFAULT_RANGE = {
from: 'now-1h',
Expand Down Expand Up @@ -145,6 +144,7 @@ export function buildQueryTransaction(
panelId,
targets: configuredQueries, // Datasources rely on DataQueries being passed under the targets key.
range,
requestId: 'explore',
rangeRaw: range.raw,
scopedVars: {
__interval: { text: interval, value: interval },
Expand Down Expand Up @@ -542,3 +542,10 @@ export const getQueryResponse = (
) => {
return from(datasourceInstance.query(options, observer));
};

export const stopQueryState = (queryState: PanelQueryState, reason: string) => {
if (queryState && queryState.isStarted()) {
queryState.cancel(reason);
queryState.closeStreams(false);
}
};
4 changes: 1 addition & 3 deletions public/app/features/dashboard/state/PanelQueryState.ts
@@ -1,18 +1,16 @@
// Libraries
import { isArray, isEqual, isString } from 'lodash';

// Utils & Services
import { getBackendSrv } from 'app/core/services/backend_srv';
import { dateMath } from '@grafana/data';
import {
dateMath,
guessFieldTypes,
LoadingState,
toLegacyResponseData,
DataFrame,
toDataFrame,
isDataFrame,
} from '@grafana/data';

// Types
import {
DataSourceApi,
Expand Down
1 change: 1 addition & 0 deletions public/app/features/explore/QueryField.tsx
Expand Up @@ -8,6 +8,7 @@ import { Editor } from 'slate-react';
// @ts-ignore
import Plain from 'slate-plain-serializer';
import classnames from 'classnames';
// @ts-ignore
import { isKeyHotkey } from 'is-hotkey';

import { CompletionItem, CompletionItemGroup, TypeaheadOutput } from 'app/types/explore';
Expand Down
75 changes: 9 additions & 66 deletions public/app/features/explore/state/actionTypes.ts
@@ -1,25 +1,9 @@
// Types
import { Emitter } from 'app/core/core';
import {
DataQuery,
DataSourceSelectItem,
DataSourceApi,
QueryFixAction,
DataQueryError,
DataQueryResponseData,
} from '@grafana/ui';

import {
RawTimeRange,
LogLevel,
TimeRange,
DataFrame,
LogsModel,
LoadingState,
AbsoluteTimeRange,
GraphSeriesXY,
} from '@grafana/data';
import { ExploreId, ExploreItemState, HistoryItem, ExploreUIState, ExploreMode, QueryOptions } from 'app/types/explore';
import { DataQuery, DataSourceSelectItem, DataSourceApi, QueryFixAction, DataQueryError } from '@grafana/ui';

import { LogLevel, TimeRange, LogsModel, LoadingState, AbsoluteTimeRange, GraphSeriesXY } from '@grafana/data';
import { ExploreId, ExploreItemState, HistoryItem, ExploreUIState, ExploreMode } from 'app/types/explore';
import { actionCreatorFactory, noPayloadActionCreatorFactory, ActionOf } from 'app/core/redux/actionCreatorFactory';
import TableModel from 'app/core/table_model';

Expand Down Expand Up @@ -230,42 +214,15 @@ export interface SetUrlReplacedPayload {
exploreId: ExploreId;
}

export interface ProcessQueryErrorsPayload {
exploreId: ExploreId;
response: any;
datasourceId: string;
}

export interface ProcessQueryResultsPayload {
exploreId: ExploreId;
latency: number;
datasourceId: string;
loadingState: LoadingState;
series?: DataQueryResponseData[];
delta?: DataFrame[];
}

export interface RunQueriesBatchPayload {
exploreId: ExploreId;
queryOptions: QueryOptions;
}

export interface LimitMessageRatePayload {
series: DataFrame[];
exploreId: ExploreId;
datasourceId: string;
}

export interface ChangeRangePayload {
exploreId: ExploreId;
range: TimeRange;
absoluteRange: AbsoluteTimeRange;
}

export interface UpdateTimeRangePayload {
export interface ChangeLoadingStatePayload {
exploreId: ExploreId;
rawRange?: RawTimeRange;
absoluteRange?: AbsoluteTimeRange;
loadingState: LoadingState;
}

/**
Expand Down Expand Up @@ -410,8 +367,6 @@ export const splitCloseAction = actionCreatorFactory<SplitCloseActionPayload>('e
*/
export const splitOpenAction = actionCreatorFactory<SplitOpenPayload>('explore/SPLIT_OPEN').create();

export const stateSaveAction = noPayloadActionCreatorFactory('explore/STATE_SAVE').create();

/**
* Update state of Explores UI elements (panels visiblity and deduplication strategy)
*/
Expand Down Expand Up @@ -460,23 +415,11 @@ export const resetQueryErrorAction = actionCreatorFactory<ResetQueryErrorPayload

export const setUrlReplacedAction = actionCreatorFactory<SetUrlReplacedPayload>('explore/SET_URL_REPLACED').create();

export const processQueryErrorsAction = actionCreatorFactory<ProcessQueryErrorsPayload>(
'explore/PROCESS_QUERY_ERRORS'
).create();

export const processQueryResultsAction = actionCreatorFactory<ProcessQueryResultsPayload>(
'explore/PROCESS_QUERY_RESULTS'
).create();

export const runQueriesBatchAction = actionCreatorFactory<RunQueriesBatchPayload>('explore/RUN_QUERIES_BATCH').create();

export const limitMessageRatePayloadAction = actionCreatorFactory<LimitMessageRatePayload>(
'explore/LIMIT_MESSAGE_RATE_PAYLOAD'
).create();

export const changeRangeAction = actionCreatorFactory<ChangeRangePayload>('explore/CHANGE_RANGE').create();

export const updateTimeRangeAction = actionCreatorFactory<UpdateTimeRangePayload>('explore/UPDATE_TIMERANGE').create();
export const changeLoadingStateAction = actionCreatorFactory<ChangeLoadingStatePayload>(
'changeLoadingStateAction'
).create();

export type HigherOrderAction =
| ActionOf<SplitCloseActionPayload>
Expand Down
24 changes: 8 additions & 16 deletions public/app/features/explore/state/actions.test.ts
Expand Up @@ -11,14 +11,12 @@ import {
testDataSourceFailureAction,
loadDatasourcePendingAction,
loadDatasourceReadyAction,
updateTimeRangeAction,
} from './actionTypes';
import { Emitter } from 'app/core/core';
import { ActionOf } from 'app/core/redux/actionCreatorFactory';
import { makeInitialUpdateState } from './reducers';
import { DataQuery } from '@grafana/ui/src/types/datasource';
import { DefaultTimeZone, RawTimeRange, LogsDedupStrategy } from '@grafana/data';
import { toUtc } from '@grafana/data';
import { DefaultTimeZone, RawTimeRange, LogsDedupStrategy, toUtc } from '@grafana/data';

jest.mock('app/features/plugins/datasource_srv', () => ({
getDatasourceSrv: () => ({
Expand All @@ -30,6 +28,12 @@ jest.mock('app/features/plugins/datasource_srv', () => ({
}),
}));

jest.mock('../../dashboard/services/TimeSrv', () => ({
getTimeSrv: jest.fn().mockReturnValue({
init: jest.fn(),
}),
}));

const t = toUtc();
const testRange = {
from: t,
Expand Down Expand Up @@ -62,6 +66,7 @@ const setup = (updateOverides?: Partial<ExploreUpdateState>) => {
const update = { ...updateDefaults, ...updateOverides };
const initialState = {
user: {
orgId: '1',
timeZone,
},
explore: {
Expand Down Expand Up @@ -118,19 +123,6 @@ describe('refreshExplore', () => {
});
});

describe('and update range is set', () => {
it('then it should dispatch updateTimeRangeAction', async () => {
const { exploreId, range, initialState } = setup({ range: true });

const dispatchedActions = await thunkTester(initialState)
.givenThunk(refreshExplore)
.whenThunkIsDispatched(exploreId);

expect(dispatchedActions[0].type).toEqual(updateTimeRangeAction.type);
expect(dispatchedActions[0].payload).toEqual({ exploreId, rawRange: range.raw });
});
});

describe('and update ui is set', () => {
it('then it should dispatch updateUIStateAction', async () => {
const { exploreId, initialState, ui } = setup({ ui: true });
Expand Down