mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
@@ -9,6 +9,7 @@ import {
|
||||
DataStreamState,
|
||||
LoadingState,
|
||||
LogLevel,
|
||||
CSVReader,
|
||||
} from '@grafana/ui';
|
||||
import { TestDataQuery, StreamingQuery } from './types';
|
||||
|
||||
@@ -57,6 +58,8 @@ export class StreamHandler {
|
||||
this.workers[key] = new SignalWorker(key, query, req, observer);
|
||||
} else if (type === 'logs') {
|
||||
this.workers[key] = new LogsWorker(key, query, req, observer);
|
||||
} else if (type === 'fetch') {
|
||||
this.workers[key] = new FetchWorker(key, query, req, observer);
|
||||
} else {
|
||||
throw {
|
||||
message: 'Unknown Stream type: ' + type,
|
||||
@@ -72,6 +75,7 @@ export class StreamHandler {
|
||||
* Manages a single stream request
|
||||
*/
|
||||
export class StreamWorker {
|
||||
refId: string;
|
||||
query: StreamingQuery;
|
||||
stream: DataStreamState;
|
||||
observer: DataStreamObserver;
|
||||
@@ -85,6 +89,7 @@ export class StreamWorker {
|
||||
request,
|
||||
unsubscribe: this.unsubscribe,
|
||||
};
|
||||
this.refId = query.refId;
|
||||
this.query = query.stream;
|
||||
this.last = Date.now();
|
||||
this.observer = observer;
|
||||
@@ -207,6 +212,56 @@ export class SignalWorker extends StreamWorker {
|
||||
};
|
||||
}
|
||||
|
||||
export class FetchWorker extends StreamWorker {
|
||||
csv: CSVReader;
|
||||
reader: ReadableStreamReader<Uint8Array>;
|
||||
|
||||
constructor(key: string, query: TestDataQuery, request: DataQueryRequest, observer: DataStreamObserver) {
|
||||
super(key, query, request, observer);
|
||||
if (!query.stream.url) {
|
||||
throw new Error('Missing Fetch URL');
|
||||
}
|
||||
if (!query.stream.url.startsWith('http')) {
|
||||
throw new Error('Fetch URL must be absolute');
|
||||
}
|
||||
|
||||
this.csv = new CSVReader({ callback: this });
|
||||
fetch(new Request(query.stream.url)).then(response => {
|
||||
this.reader = response.body.getReader();
|
||||
this.reader.read().then(this.processChunk);
|
||||
});
|
||||
}
|
||||
|
||||
processChunk = (value: ReadableStreamReadResult<Uint8Array>): any => {
|
||||
if (this.observer == null) {
|
||||
return; // Nothing more to do
|
||||
}
|
||||
|
||||
if (value.value) {
|
||||
const text = new TextDecoder().decode(value.value);
|
||||
this.csv.readCSV(text);
|
||||
}
|
||||
|
||||
if (value.done) {
|
||||
console.log('Finished stream');
|
||||
this.stream.state = LoadingState.Done;
|
||||
return;
|
||||
}
|
||||
|
||||
return this.reader.read().then(this.processChunk);
|
||||
};
|
||||
|
||||
onHeader = (series: SeriesData) => {
|
||||
series.refId = this.refId;
|
||||
this.stream.series = [series];
|
||||
};
|
||||
|
||||
onRow = (row: any[]) => {
|
||||
// TODO?? this will send an event for each row, even if the chunk passed a bunch of them
|
||||
this.appendRows([row]);
|
||||
};
|
||||
}
|
||||
|
||||
export class LogsWorker extends StreamWorker {
|
||||
index = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user