From e17fd5e8ad42d78752909ab90d9c6a73613efc30 Mon Sep 17 00:00:00 2001 From: Victor Marin <36818606+mdvictor@users.noreply.github.com> Date: Tue, 11 Feb 2025 13:39:00 +0200 Subject: [PATCH] DashboardDS: Re-run dashboard queries within MixedDS on transformation reprocessing (#100370) * fix scenario where results subscription is lost due to transformations * fix --- .../DashboardDatasourceBehaviour.test.tsx | 63 +++++++++++++++++++ .../scene/DashboardDatasourceBehaviour.tsx | 29 ++++++--- 2 files changed, 85 insertions(+), 7 deletions(-) diff --git a/public/app/features/dashboard-scene/scene/DashboardDatasourceBehaviour.test.tsx b/public/app/features/dashboard-scene/scene/DashboardDatasourceBehaviour.test.tsx index 1b183577b1f..59a27eacaad 100644 --- a/public/app/features/dashboard-scene/scene/DashboardDatasourceBehaviour.test.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardDatasourceBehaviour.test.tsx @@ -6,6 +6,7 @@ import { DataSourceApi, DataSourceJsonData, DataSourceRef, + getDefaultTimeRange, LoadingState, PanelData, } from '@grafana/data'; @@ -593,6 +594,68 @@ describe('DashboardDatasourceBehaviour', () => { expect(spy).toHaveBeenCalled(); }); }); + + it('Should re-run query after transformations reprocess', async () => { + const sourcePanel = new VizPanel({ + title: 'Panel A', + pluginId: 'table', + key: 'panel-1', + $data: new SceneDataTransformer({ + transformations: [{ id: 'transformA', options: {} }], + $data: new SceneQueryRunner({ + datasource: { uid: 'grafana' }, + queries: [{ refId: 'A', queryType: 'randomWalk' }], + }), + }), + }); + + const dashboardDSPanel = new VizPanel({ + title: 'Panel B', + pluginId: 'table', + key: 'panel-2', + $data: new SceneDataTransformer({ + transformations: [], + $data: new SceneQueryRunner({ + datasource: { uid: MIXED_DATASOURCE_NAME }, + queries: [ + { + datasource: { uid: SHARED_DASHBOARD_QUERY }, + refId: 'B', + panelId: 1, + }, + ], + $behaviors: [new DashboardDatasourceBehaviour({})], + }), + }), + }); + + const scene = new DashboardScene({ + title: 'hello', + uid: 'dash-1', + meta: { + canEdit: true, + }, + body: DefaultGridLayoutManager.fromVizPanels([sourcePanel, dashboardDSPanel]), + }); + + activateFullSceneTree(scene); + + await new Promise((r) => setTimeout(r, 1)); + + // spy on runQueries that will be called by the behaviour + const spy = jest + .spyOn(dashboardDSPanel.state.$data!.state.$data as SceneQueryRunner, 'runQueries') + .mockImplementation(); + + // transformations are reprocessed (e.g. variable change) and data is updated so + // we re-run the queries in the dashboardDS panel because we lose the subscription + // in mixed DS scenario + (sourcePanel.state.$data as SceneDataTransformer).setState({ + data: { state: LoadingState.Done, series: [], timeRange: getDefaultTimeRange() }, + }); + + expect(spy).toHaveBeenCalled(); + }); }); async function buildTestScene() { diff --git a/public/app/features/dashboard-scene/scene/DashboardDatasourceBehaviour.tsx b/public/app/features/dashboard-scene/scene/DashboardDatasourceBehaviour.tsx index fcbab5cc59b..940b4077d8d 100644 --- a/public/app/features/dashboard-scene/scene/DashboardDatasourceBehaviour.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardDatasourceBehaviour.tsx @@ -1,6 +1,6 @@ import { Unsubscribable } from 'rxjs'; -import { SceneObjectBase, SceneObjectState, SceneQueryRunner, VizPanel } from '@grafana/scenes'; +import { SceneDataTransformer, SceneObjectBase, SceneObjectState, SceneQueryRunner, VizPanel } from '@grafana/scenes'; import { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard/constants'; import { MIXED_DATASOURCE_NAME } from 'app/plugins/datasource/mixed/MixedDataSource'; @@ -28,6 +28,7 @@ export class DashboardDatasourceBehaviour extends SceneObjectBase { + if (newState.data !== oldState.data) { + queryRunner.runQueries(); + } + }); + } + if (this.prevRequestId && this.prevRequestId !== sourcePanelQueryRunner.state.data?.request?.requestId) { queryRunner.runQueries(); } @@ -82,6 +97,10 @@ export class DashboardDatasourceBehaviour extends SceneObjectBase query.datasource?.uid === SHARED_DASHBOARD_QUERY) - ) { - return true; - } - - return false; + ); } private handleLibPanelStateUpdates(