|
|
@ -1,8 +1,8 @@ |
|
|
|
import { DataFrame, FieldType, parseLabels, KeyValue, CircularDataFrame } from '@grafana/data'; |
|
|
|
import { DataFrame, FieldType, parseLabels, KeyValue, CircularDataFrame } from '@grafana/data'; |
|
|
|
import { Observable, throwError } from 'rxjs'; |
|
|
|
import { Observable, throwError, timer } from 'rxjs'; |
|
|
|
import { webSocket } from 'rxjs/webSocket'; |
|
|
|
import { webSocket } from 'rxjs/webSocket'; |
|
|
|
import { LokiTailResponse } from './types'; |
|
|
|
import { LokiTailResponse } from './types'; |
|
|
|
import { finalize, map, catchError } from 'rxjs/operators'; |
|
|
|
import { finalize, map, retryWhen, mergeMap } from 'rxjs/operators'; |
|
|
|
import { appendResponseToBufferedData } from './result_transformer'; |
|
|
|
import { appendResponseToBufferedData } from './result_transformer'; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -22,7 +22,7 @@ export interface LokiLiveTarget { |
|
|
|
export class LiveStreams { |
|
|
|
export class LiveStreams { |
|
|
|
private streams: KeyValue<Observable<DataFrame[]>> = {}; |
|
|
|
private streams: KeyValue<Observable<DataFrame[]>> = {}; |
|
|
|
|
|
|
|
|
|
|
|
getStream(target: LokiLiveTarget): Observable<DataFrame[]> { |
|
|
|
getStream(target: LokiLiveTarget, retryInterval = 5000): Observable<DataFrame[]> { |
|
|
|
let stream = this.streams[target.url]; |
|
|
|
let stream = this.streams[target.url]; |
|
|
|
|
|
|
|
|
|
|
|
if (stream) { |
|
|
|
if (stream) { |
|
|
@ -42,9 +42,27 @@ export class LiveStreams { |
|
|
|
appendResponseToBufferedData(response, data); |
|
|
|
appendResponseToBufferedData(response, data); |
|
|
|
return [data]; |
|
|
|
return [data]; |
|
|
|
}), |
|
|
|
}), |
|
|
|
catchError(err => { |
|
|
|
retryWhen((attempts: Observable<any>) => |
|
|
|
return throwError(`error: ${err.reason}`); |
|
|
|
attempts.pipe( |
|
|
|
}), |
|
|
|
mergeMap((error, i) => { |
|
|
|
|
|
|
|
const retryAttempt = i + 1; |
|
|
|
|
|
|
|
// Code 1006 is used to indicate that a connection was closed abnormally.
|
|
|
|
|
|
|
|
// Added hard limit of 30 on number of retries.
|
|
|
|
|
|
|
|
// If connection was closed abnormally, and we wish to retry, otherwise throw error.
|
|
|
|
|
|
|
|
if (error.code === 1006 && retryAttempt < 30) { |
|
|
|
|
|
|
|
if (retryAttempt > 10) { |
|
|
|
|
|
|
|
// If more than 10 times retried, consol.warn, but keep reconnecting
|
|
|
|
|
|
|
|
console.warn( |
|
|
|
|
|
|
|
`Websocket connection is being disrupted. We keep reconnecting but consider starting new live tailing again. Error: ${error.reason}` |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Retry every 5s
|
|
|
|
|
|
|
|
return timer(retryInterval); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return throwError(`error: ${error.reason}`); |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
), |
|
|
|
finalize(() => { |
|
|
|
finalize(() => { |
|
|
|
delete this.streams[target.url]; |
|
|
|
delete this.streams[target.url]; |
|
|
|
}) |
|
|
|
}) |
|
|
|