From b9fba9584921f792d7a6df0e9591418be49f1c38 Mon Sep 17 00:00:00 2001 From: Yash Suresh Chandra Date: Mon, 7 Jul 2025 17:36:01 +0530 Subject: [PATCH] Dashboard: Fix cache validation to prevent stale cache (#105918) * compare dashboard updated at while fetching * test added * added created field in dashboard dto meta object for k8s api. fixed cache updation check * code refactor * code formatting with prettier * added created at field in DashboardPageProxy.test.tsx --- .../DashboardScenePageStateManager.test.ts | 33 +++++++++++++++++++ .../pages/DashboardScenePageStateManager.ts | 6 +++- public/app/features/dashboard/api/v1.ts | 1 + .../containers/DashboardPageProxy.test.tsx | 1 + 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/public/app/features/dashboard-scene/pages/DashboardScenePageStateManager.test.ts b/public/app/features/dashboard-scene/pages/DashboardScenePageStateManager.test.ts index 5e8b9cd57ca..287140082c7 100644 --- a/public/app/features/dashboard-scene/pages/DashboardScenePageStateManager.test.ts +++ b/public/app/features/dashboard-scene/pages/DashboardScenePageStateManager.test.ts @@ -218,6 +218,39 @@ describe('DashboardScenePageStateManager v1', () => { }); describe('caching', () => { + it('should return cached scene if updated_at matches', async () => { + const loader = new DashboardScenePageStateManager({}); + + // set cache + loader.setSceneCache( + 'fake-dash', + new DashboardScene({ title: 'Dashboard 1', uid: 'fake-dash', meta: { created: '1' }, version: 0 }, 'v1') + ); + + // should return cached scene + expect( + loader.transformResponseToScene( + { + meta: { created: '1' }, + dashboard: { title: 'Dashboard 1', uid: 'fake-dash', schemaVersion: 1, version: 0 }, + }, + { uid: 'fake-dash', route: DashboardRoutes.Normal } + )?.state.title + ).toBe('Dashboard 1'); + + // try loading new scene + loader.transformResponseToScene( + { + meta: { created: '2' }, + dashboard: { title: 'Dashboard 2', uid: 'fake-dash', schemaVersion: 1, version: 0 }, + }, + { uid: 'fake-dash', route: DashboardRoutes.Normal } + ); + + // should update cache with new scene + expect(loader.getSceneFromCache('fake-dash').state.title).toBe('Dashboard 2'); + }); + it('should take scene from cache if it exists', async () => { setupLoadDashboardMock({ dashboard: { uid: 'fake-dash', version: 10 }, meta: {} }); diff --git a/public/app/features/dashboard-scene/pages/DashboardScenePageStateManager.ts b/public/app/features/dashboard-scene/pages/DashboardScenePageStateManager.ts index e143df2b776..e6c2cb3e0a8 100644 --- a/public/app/features/dashboard-scene/pages/DashboardScenePageStateManager.ts +++ b/public/app/features/dashboard-scene/pages/DashboardScenePageStateManager.ts @@ -371,7 +371,11 @@ export class DashboardScenePageStateManager extends DashboardScenePageStateManag transformResponseToScene(rsp: DashboardDTO | null, options: LoadDashboardOptions): DashboardScene | null { const fromCache = this.getSceneFromCache(options.uid); - if (fromCache && fromCache.state.version === rsp?.dashboard.version) { + if ( + fromCache && + fromCache.state.version === rsp?.dashboard.version && + fromCache.state.meta.created === rsp?.meta.created + ) { return fromCache; } diff --git a/public/app/features/dashboard/api/v1.ts b/public/app/features/dashboard/api/v1.ts index 58edcc56d70..58708bcdcd8 100644 --- a/public/app/features/dashboard/api/v1.ts +++ b/public/app/features/dashboard/api/v1.ts @@ -128,6 +128,7 @@ export class K8sDashboardAPI implements DashboardAPI { uid: dash.metadata.name, k8s: dash.metadata, version: dash.metadata.generation, + created: dash.metadata.creationTimestamp, }, dashboard: { ...dash.spec, diff --git a/public/app/features/dashboard/containers/DashboardPageProxy.test.tsx b/public/app/features/dashboard/containers/DashboardPageProxy.test.tsx index 7b206a79e44..ee38959345f 100644 --- a/public/app/features/dashboard/containers/DashboardPageProxy.test.tsx +++ b/public/app/features/dashboard/containers/DashboardPageProxy.test.tsx @@ -33,6 +33,7 @@ const dashMock: DashboardDTO = { }, meta: { canEdit: false, + created: 'Friday, 4 July 2025 07:56:41 GMT+05:30', }, };