Range splitting: Read errors from the received response and report them (#63368)

This commit is contained in:
Matias Chomicki 2023-02-16 18:39:26 +01:00 committed by GitHub
parent 0659134793
commit a0bea04a02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 24 deletions

View File

@ -2,6 +2,7 @@ import { of } from 'rxjs';
import { getQueryOptions } from 'test/helpers/getQueryOptions'; import { getQueryOptions } from 'test/helpers/getQueryOptions';
import { dateTime } from '@grafana/data'; import { dateTime } from '@grafana/data';
import { LoadingState } from '@grafana/schema';
import { LokiDatasource } from './datasource'; import { LokiDatasource } from './datasource';
import * as logsTimeSplit from './logsTimeSplit'; import * as logsTimeSplit from './logsTimeSplit';
@ -36,6 +37,15 @@ describe('runPartitionedQuery()', () => {
}); });
}); });
test('Handles and reports rerrors', async () => {
jest
.spyOn(datasource, 'runQuery')
.mockReturnValue(of({ state: LoadingState.Error, error: { refId: 'A', message: 'Error' }, data: [] }));
await expect(runPartitionedQuery(datasource, request)).toEmitValuesWith((values) => {
expect(values).toEqual([{ refId: 'A', message: 'Error' }]);
});
});
describe('Hidden queries', () => { describe('Hidden queries', () => {
const request = getQueryOptions<LokiQuery>({ const request = getQueryOptions<LokiQuery>({
targets: [ targets: [

View File

@ -1,4 +1,4 @@
import { Subscriber, map, Observable, Subscription } from 'rxjs'; import { Subscriber, Observable, Subscription } from 'rxjs';
import { DataQueryRequest, DataQueryResponse, dateTime, TimeRange } from '@grafana/data'; import { DataQueryRequest, DataQueryResponse, dateTime, TimeRange } from '@grafana/data';
import { LoadingState } from '@grafana/schema'; import { LoadingState } from '@grafana/schema';
@ -103,6 +103,7 @@ export function runPartitionedQuery(datasource: LokiDatasource, request: DataQue
let subquerySubsciption: Subscription | null = null; let subquerySubsciption: Subscription | null = null;
const runNextRequest = (subscriber: Subscriber<DataQueryResponse>, requestN: number) => { const runNextRequest = (subscriber: Subscriber<DataQueryResponse>, requestN: number) => {
if (shouldStop) { if (shouldStop) {
subscriber.complete();
return; return;
} }
@ -116,34 +117,36 @@ export function runPartitionedQuery(datasource: LokiDatasource, request: DataQue
subscriber.complete(); subscriber.complete();
}; };
const nextRequest = () => {
mergedResponse = mergedResponse || { data: [] };
if (requestN > 1) {
mergedResponse.state = LoadingState.Streaming;
subscriber.next(mergedResponse);
runNextRequest(subscriber, requestN - 1);
return;
}
done(mergedResponse);
};
if (!targets.length && mergedResponse) { if (!targets.length && mergedResponse) {
done(mergedResponse); done(mergedResponse);
return; return;
} }
subquerySubsciption = datasource subquerySubsciption = datasource.runQuery({ ...request, range, requestId, targets }).subscribe({
.runQuery({ ...request, range, requestId, targets }) next: (partialResponse) => {
.pipe( if (partialResponse.error) {
// in case of an empty query, this is somehow run twice. `share()` is no workaround here as the observable is generated from `of()`. subscriber.error(partialResponse.error);
map((partialResponse) => { }
mergedResponse = combineResponses(mergedResponse, partialResponse); mergedResponse = combineResponses(mergedResponse, partialResponse);
return mergedResponse; },
}) complete: () => {
) nextRequest();
.subscribe({ },
next: (response) => { error: (error) => {
if (requestN > 1) { subscriber.error(error);
response.state = LoadingState.Streaming; },
subscriber.next(response); });
runNextRequest(subscriber, requestN - 1);
return;
}
done(response);
},
error: (error) => {
subscriber.error(error);
},
});
}; };
const response = new Observable<DataQueryResponse>((subscriber) => { const response = new Observable<DataQueryResponse>((subscriber) => {