diff --git a/public/app/features/query/state/DashboardQueryRunner/DashboardQueryRunner.ts b/public/app/features/query/state/DashboardQueryRunner/DashboardQueryRunner.ts index 06be38c5c43..4a708ebc0dc 100644 --- a/public/app/features/query/state/DashboardQueryRunner/DashboardQueryRunner.ts +++ b/public/app/features/query/state/DashboardQueryRunner/DashboardQueryRunner.ts @@ -1,5 +1,5 @@ -import { merge, Observable, Subject, Unsubscribable } from 'rxjs'; -import { map, mergeAll, reduce, share, takeUntil } from 'rxjs/operators'; +import { merge, Observable, ReplaySubject, Subject, Unsubscribable } from 'rxjs'; +import { mergeAll, reduce, share, takeUntil } from 'rxjs/operators'; import { AnnotationQuery } from '@grafana/data'; import { dedupAnnotations } from 'app/features/annotations/events_processing'; @@ -13,13 +13,13 @@ import { import { AlertStatesWorker } from './AlertStatesWorker'; import { SnapshotWorker } from './SnapshotWorker'; import { AnnotationsWorker } from './AnnotationsWorker'; -import { getAnnotationsByPanelId } from './utils'; +import { emptyResult, getAnnotationsByPanelId } from './utils'; import { DashboardModel } from '../../../dashboard/state'; import { getTimeSrv, TimeSrv } from '../../../dashboard/services/TimeSrv'; import { RefreshEvent } from '../../../../types/events'; class DashboardQueryRunnerImpl implements DashboardQueryRunner { - private readonly results: Subject; + private readonly results: ReplaySubject; private readonly runs: Subject; private readonly cancellationStream: Subject; private readonly runsSubscription: Unsubscribable; @@ -39,7 +39,7 @@ class DashboardQueryRunnerImpl implements DashboardQueryRunner { this.cancel = this.cancel.bind(this); this.destroy = this.destroy.bind(this); this.executeRun = this.executeRun.bind(this); - this.results = new Subject(); + this.results = new ReplaySubject(); this.runs = new Subject(); this.cancellationStream = new Subject(); this.runsSubscription = this.runs.subscribe((options) => this.executeRun(options)); @@ -53,21 +53,26 @@ class DashboardQueryRunnerImpl implements DashboardQueryRunner { } getResult(panelId?: number): Observable { - return this.results.asObservable().pipe( - map((result) => { - const annotations = getAnnotationsByPanelId(result.annotations, panelId); - - const alertState = result.alertStates.find((res) => Boolean(panelId) && res.panelId === panelId); - - return { annotations: dedupAnnotations(annotations), alertState }; - }), - share() // sharing this so we can merge this with it self in mergePanelAndDashData - ); + return new Observable((subscriber) => { + const subscription = this.results.subscribe({ + next: (result) => { + const annotations = getAnnotationsByPanelId(result.annotations, panelId); + const alertState = result.alertStates.find((res) => Boolean(panelId) && res.panelId === panelId); + subscriber.next({ annotations: dedupAnnotations(annotations), alertState }); + }, + error: subscriber.error, + complete: subscriber.complete, + }); + return () => { + subscription.unsubscribe(); + }; + }); } private executeRun(options: DashboardQueryRunnerOptions) { const workers = this.workers.filter((w) => w.canWork(options)); - const observables = workers.map((w) => w.work(options)); + const workerObservables = workers.map((w) => w.work(options)); + const observables = [emptyResult()].concat(workerObservables); merge(observables) .pipe( diff --git a/public/app/features/query/state/PanelQueryRunner.ts b/public/app/features/query/state/PanelQueryRunner.ts index 914b6f46fd2..b2c885357a9 100644 --- a/public/app/features/query/state/PanelQueryRunner.ts +++ b/public/app/features/query/state/PanelQueryRunner.ts @@ -32,6 +32,7 @@ import { } from '@grafana/data'; import { getDashboardQueryRunner } from './DashboardQueryRunner/DashboardQueryRunner'; import { mergePanelAndDashData } from './mergePanelAndDashData'; +import { PanelModel } from '../../dashboard/state'; export interface QueryRunnerOptions< TQuery extends DataQuery = DataQuery, @@ -255,7 +256,9 @@ export class PanelQueryRunner { const dataSupport = this.dataConfigSource.getDataSupport(); if (dataSupport.alertStates || dataSupport.annotations) { - panelData = mergePanelAndDashData(observable, getDashboardQueryRunner().getResult(panelId)); + const panel = (this.dataConfigSource as unknown) as PanelModel; + const id = panel.editSourceId ?? panel.id; + panelData = mergePanelAndDashData(observable, getDashboardQueryRunner().getResult(id)); } this.subscription = panelData.subscribe({