Skip to content

Commit b6f265f

Browse files
authored
asyncQueryDataSupport: always run queries asynchronously (#30)
- Removes feature toggle for async queries
1 parent 6e35a83 commit b6f265f

File tree

6 files changed

+59
-88
lines changed

6 files changed

+59
-88
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## v0.2.0
6+
7+
- Remove athenaAsyncQueryDataSupport and redshiftAsyncQueryData feature toggle-related code
8+
59
## v0.1.11
610

711
- Support Node 18 (#25)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@grafana/async-query-data",
3-
"version": "0.1.11",
3+
"version": "0.2.0",
44
"description": "Async query support for Grafana",
55
"main": "dist/index.js",
66
"scripts": {

src/DatasourceWithAsyncBackend.test.ts

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -62,28 +62,23 @@ const defaultRequest = {
6262
startTime: 0,
6363
};
6464

65-
const setupDatasourceWithAsyncBackend = ({
66-
settings = defaultInstanceSettings,
67-
asyncQueryDataSupport = true,
68-
}: {
69-
settings?: DataSourceInstanceSettings<{}>;
70-
asyncQueryDataSupport?: boolean;
71-
}) => new DatasourceWithAsyncBackend<DataQuery>(settings, asyncQueryDataSupport);
65+
const setupDatasourceWithAsyncBackend = (settings: DataSourceInstanceSettings = defaultInstanceSettings) =>
66+
new DatasourceWithAsyncBackend<DataQuery>(settings);
7267

7368
describe('DatasourceWithAsyncBackend', () => {
7469
// beforeAll(() => {
7570
// queryMock.mockClear();
7671
// });
7772

7873
it('can store running queries', () => {
79-
const ds = setupDatasourceWithAsyncBackend({});
74+
const ds = setupDatasourceWithAsyncBackend();
8075

8176
ds.storeQuery(defaultQuery, { queryID: '123' });
8277
expect(ds.getQuery(defaultQuery)).toEqual({ queryID: '123' });
8378
});
8479

8580
it('can remove running queries', () => {
86-
const ds = setupDatasourceWithAsyncBackend({});
81+
const ds = setupDatasourceWithAsyncBackend();
8782

8883
ds.storeQuery(defaultQuery, { queryID: '123' });
8984
expect(ds.getQuery(defaultQuery)).toEqual({ queryID: '123' });
@@ -92,15 +87,15 @@ describe('DatasourceWithAsyncBackend', () => {
9287
});
9388

9489
it('can cancel running queries', () => {
95-
const ds = setupDatasourceWithAsyncBackend({});
90+
const ds = setupDatasourceWithAsyncBackend();
9691

9792
ds.storeQuery(defaultQuery, { queryID: '123' });
9893
ds.cancel(defaultQuery);
9994
expect(ds.getQuery(defaultQuery)).toEqual({ queryID: '123', shouldCancel: true });
10095
});
10196

102-
it('can queue individual queries to run asynchronously if feature toggle asyncQueryDataSupport is `true`', () => {
103-
const ds = setupDatasourceWithAsyncBackend({ asyncQueryDataSupport: true });
97+
it('will queue individual queries to run asynchronously', () => {
98+
const ds = setupDatasourceWithAsyncBackend();
10499

105100
ds.doSingle = jest.fn().mockReturnValue(Promise.resolve({ data: [] }));
106101
expect(ds.doSingle).not.toHaveBeenCalled();
@@ -110,19 +105,8 @@ describe('DatasourceWithAsyncBackend', () => {
110105
expect(ds.doSingle).toHaveBeenCalledWith(defaultQuery2, defaultRequest);
111106
});
112107

113-
it('can run queries synchronously if feature toggle asyncQueryDataSupport is `false`', () => {
114-
const ds = setupDatasourceWithAsyncBackend({ asyncQueryDataSupport: false });
115-
116-
ds.doSingle = jest.fn();
117-
expect(ds.doSingle).not.toHaveBeenCalled();
118-
ds.query(defaultRequest);
119-
expect(ds.doSingle).not.toHaveBeenCalled();
120-
expect(queryMock).toHaveBeenCalledTimes(1);
121-
expect(queryMock).toHaveBeenCalledWith(defaultRequest);
122-
});
123-
124108
it('uses the datasource id for the request id', () => {
125-
const ds = setupDatasourceWithAsyncBackend({ asyncQueryDataSupport: true });
109+
const ds = setupDatasourceWithAsyncBackend();
126110
expect(getRequestLooperMock).not.toHaveBeenCalled();
127111
ds.doSingle(defaultQuery, defaultRequest);
128112
expect(getRequestLooperMock).toHaveBeenCalledTimes(1);

src/DatasourceWithAsyncBackend.ts

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,36 +39,30 @@ const isCustomMeta = (meta: unknown): meta is CustomMeta => {
3939

4040
export class DatasourceWithAsyncBackend<
4141
TQuery extends DataQuery = DataQuery,
42-
TOptions extends DataSourceJsonData = DataSourceJsonData
42+
TOptions extends DataSourceJsonData = DataSourceJsonData,
4343
> extends DataSourceWithBackend<TQuery, TOptions> {
4444
private runningQueries: { [hash: string]: RunningQueryInfo } = {};
4545
private requestCounter = 100;
46-
private asyncQueryDataSupport: boolean;
4746
private requestIdPrefix: number;
4847

49-
constructor(instanceSettings: DataSourceInstanceSettings<TOptions>, asyncQueryDataSupport = false) {
48+
constructor(instanceSettings: DataSourceInstanceSettings<TOptions>) {
5049
super(instanceSettings);
5150
this.requestIdPrefix = instanceSettings.id;
52-
this.asyncQueryDataSupport = asyncQueryDataSupport;
5351
}
5452

5553
query(request: DataQueryRequest<TQuery>): Observable<DataQueryResponse> {
56-
if (this.asyncQueryDataSupport) {
57-
const targets = this.filterQuery ? request.targets.filter(this.filterQuery) : request.targets;
58-
if (!targets.length) {
59-
return of({ data: [] });
60-
}
61-
const all: Array<Observable<DataQueryResponse>> = [];
62-
for (let target of targets) {
63-
if (target.hide) {
64-
continue;
65-
}
66-
all.push(this.doSingle(target, request));
54+
const targets = this.filterQuery ? request.targets.filter(this.filterQuery) : request.targets;
55+
if (!targets.length) {
56+
return of({ data: [] });
57+
}
58+
const all: Array<Observable<DataQueryResponse>> = [];
59+
for (let target of targets) {
60+
if (target.hide) {
61+
continue;
6762
}
68-
return merge(...all);
69-
} else {
70-
return super.query(request);
63+
all.push(this.doSingle(target, request));
7164
}
65+
return merge(...all);
7266
}
7367

7468
storeQuery(target: TQuery, queryInfo: RunningQueryInfo) {
@@ -123,7 +117,7 @@ export class DatasourceWithAsyncBackend<
123117
const [_query] = targets;
124118
const query: TQuery & DataQueryMeta = {
125119
..._query,
126-
...(this.asyncQueryDataSupport ? { meta: { queryFlow: 'async' } } : {}),
120+
meta: { queryFlow: 'async' },
127121
};
128122

129123
const data = {

src/RunQueryButtons.test.tsx

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import {fireEvent, render, screen} from '@testing-library/react';
2+
import { fireEvent, render, screen } from '@testing-library/react';
33

44
import { DataQuery } from '@grafana/data';
55
import { RunQueryButtons, RunQueryButtonsProps } from './RunQueryButtons';
@@ -15,38 +15,29 @@ const getDefaultProps = (overrides?: Partial<RunQueryButtonsProps<DataQuery>>) =
1515
};
1616

1717
describe('RunQueryButtons', () => {
18+
it('renders the `Run` and `Stop` buttons', () => {
19+
const props = getDefaultProps();
20+
render(<RunQueryButtons {...props} />);
21+
const runButton = screen.getByRole('button', { name: 'Run query' });
22+
expect(runButton).toBeInTheDocument();
23+
const stopButton = screen.queryByRole('button', { name: 'Stop query' });
24+
expect(stopButton).toBeInTheDocument();
25+
});
26+
1827
it('disable the run button if the if the enableRun button is false', () => {
19-
const props = getDefaultProps({ enableRun: false});
28+
const props = getDefaultProps({ enableRun: false });
2029
render(<RunQueryButtons {...props} />);
2130
const runButton = screen.getByRole('button', { name: 'Run query' });
2231
expect(runButton).toBeDisabled();
2332
});
2433

2534
it('run button should be enabled if the enableRun button is true', () => {
26-
const props = getDefaultProps({ enableRun: true});
35+
const props = getDefaultProps({ enableRun: true });
2736
render(<RunQueryButtons {...props} />);
2837
const runButton = screen.getByRole('button', { name: 'Run query' });
2938
expect(runButton).not.toBeDisabled();
3039
});
3140

32-
it('only renders the `Run` button if onCancelQuery is undefined', () => {
33-
const props = getDefaultProps({ onCancelQuery: undefined });
34-
render(<RunQueryButtons {...props} />);
35-
const runButton = screen.getByRole('button', { name: 'Run query' });
36-
expect(runButton).toBeInTheDocument();
37-
const stopButton = screen.queryByRole('button', { name: 'Stop query' });
38-
expect(stopButton).not.toBeInTheDocument();
39-
});
40-
41-
it('renders the `Run` and `Stop` buttons if onCancelQuery defined', () => {
42-
const props = getDefaultProps();
43-
render(<RunQueryButtons {...props} />);
44-
const runButton = screen.getByRole('button', { name: 'Run query' });
45-
expect(runButton).toBeInTheDocument();
46-
const stopButton = screen.queryByRole('button', { name: 'Stop query' });
47-
expect(stopButton).toBeInTheDocument();
48-
});
49-
5041
it('Stop query button should be disabled until run button is clicked', () => {
5142
const props = getDefaultProps();
5243
render(<RunQueryButtons {...props} />);

src/RunQueryButtons.tsx

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { DataQuery, LoadingState } from '@grafana/data';
55
export interface RunQueryButtonsProps<TQuery extends DataQuery> {
66
enableRun?: boolean;
77
onRunQuery: () => void;
8-
onCancelQuery?: (query: TQuery) => void;
8+
onCancelQuery: (query: TQuery) => void;
99
query: TQuery;
1010
state?: LoadingState;
1111
}
@@ -40,27 +40,25 @@ export const RunQueryButtons = <TQuery extends DataQuery>(props: RunQueryButtons
4040
: undefined;
4141

4242
return (
43-
<>
44-
<Button
45-
variant={props.enableRun ? 'primary' : 'secondary'}
46-
size="sm"
47-
onClick={onRunQuery}
48-
icon={running && !stopping ? 'fa fa-spinner' : undefined}
49-
disabled={state === LoadingState.Loading || !props.enableRun}
50-
>
51-
Run query
52-
</Button>
53-
{onCancelQuery &&
54-
<Button
55-
variant={running && !stopping ? 'primary' : 'secondary'}
56-
size="sm"
57-
disabled={!running || stopping}
58-
icon={stopping ? 'fa fa-spinner' : undefined}
59-
onClick={onCancelQuery}
60-
>
61-
Stop query
62-
</Button>
63-
}
64-
</>
43+
<>
44+
<Button
45+
variant={props.enableRun ? 'primary' : 'secondary'}
46+
size="sm"
47+
onClick={onRunQuery}
48+
icon={running && !stopping ? 'fa fa-spinner' : undefined}
49+
disabled={state === LoadingState.Loading || !props.enableRun}
50+
>
51+
Run query
52+
</Button>
53+
<Button
54+
variant={running && !stopping ? 'primary' : 'secondary'}
55+
size="sm"
56+
disabled={!running || stopping}
57+
icon={stopping ? 'fa fa-spinner' : undefined}
58+
onClick={onCancelQuery}
59+
>
60+
Stop query
61+
</Button>
62+
</>
6563
);
6664
};

0 commit comments

Comments
 (0)