Live: support streaming results out-of-the-box (#32821)
This commit is contained in:
@@ -7,11 +7,15 @@ import {
|
||||
DataSourceJsonData,
|
||||
ScopedVars,
|
||||
makeClassES5Compatible,
|
||||
DataFrame,
|
||||
parseLiveChannelAddress,
|
||||
StreamingFrameOptions,
|
||||
} from '@grafana/data';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map, catchError } from 'rxjs/operators';
|
||||
import { merge, Observable, of } from 'rxjs';
|
||||
import { catchError, switchMap } from 'rxjs/operators';
|
||||
import { getBackendSrv, getDataSourceSrv } from '../services';
|
||||
import { BackendDataSourceResponse, toDataQueryResponse } from './queryResponse';
|
||||
import { getLiveDataStream } from './liveQuery';
|
||||
|
||||
const ExpressionDatasourceID = '__expr__';
|
||||
|
||||
@@ -132,8 +136,13 @@ class DataSourceWithBackend<
|
||||
requestId,
|
||||
})
|
||||
.pipe(
|
||||
map((rsp) => {
|
||||
return toDataQueryResponse(rsp, queries as DataQuery[]);
|
||||
switchMap((raw) => {
|
||||
const rsp = toDataQueryResponse(raw, queries as DataQuery[]);
|
||||
// Check if any response should subscribe to a live stream
|
||||
if (rsp.data?.length && rsp.data.find((f: DataFrame) => f.meta?.channel)) {
|
||||
return toStreamingDataResponse(request, rsp);
|
||||
}
|
||||
return of(rsp);
|
||||
}),
|
||||
catchError((err) => {
|
||||
return of(toDataQueryResponse(err));
|
||||
@@ -209,6 +218,44 @@ class DataSourceWithBackend<
|
||||
}
|
||||
}
|
||||
|
||||
export function toStreamingDataResponse(
|
||||
request: DataQueryRequest,
|
||||
rsp: DataQueryResponse
|
||||
): Observable<DataQueryResponse> {
|
||||
const buffer: StreamingFrameOptions = {
|
||||
maxLength: request.maxDataPoints ?? 500,
|
||||
};
|
||||
|
||||
// For recent queries, clamp to the current time range
|
||||
if (request.rangeRaw?.to === 'now') {
|
||||
buffer.maxDelta = request.range.to.valueOf() - request.range.from.valueOf();
|
||||
}
|
||||
|
||||
const staticdata: DataFrame[] = [];
|
||||
const streams: Array<Observable<DataQueryResponse>> = [];
|
||||
for (const frame of rsp.data) {
|
||||
const addr = parseLiveChannelAddress(frame.meta?.channel);
|
||||
if (addr) {
|
||||
streams.push(
|
||||
getLiveDataStream({
|
||||
addr,
|
||||
buffer,
|
||||
frame: frame as DataFrame,
|
||||
})
|
||||
);
|
||||
} else {
|
||||
staticdata.push(frame);
|
||||
}
|
||||
}
|
||||
if (staticdata.length) {
|
||||
streams.push(of({ ...rsp, data: staticdata }));
|
||||
}
|
||||
if (streams.length === 1) {
|
||||
return streams[0]; // avoid merge wrapper
|
||||
}
|
||||
return merge(...streams);
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
DataSourceWithBackend = makeClassES5Compatible(DataSourceWithBackend);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user