From cba8f3ed52279ebee073c5e3a447e96d082fd144 Mon Sep 17 00:00:00 2001 From: Thomas Hardy Date: Thu, 13 Jul 2023 14:51:04 -0400 Subject: [PATCH] cluster-ui: skip undefined regions on database pages This patch skips `undefined` regions on the databases pages. The `undefined` behaviour occurs when we try to match a database's node IDs (i.e. the nodes with ranges that contain data belong to one of the database's tables) from the database details endpoint, to nodes' region information from the nodes endpoint. The nodes endpoint is authoritative and is refreshed at a regular interval. However, the database details endpoint is only fetched once on page load, and it's node information comes from a cache, leading to the potential of stale data (this information is authoritative in 23.1, but not in 22.2). Consequently when trying to match cached node IDs with recent node regions information, we can come across behaviour where we try to get region information for a node ID that is no longer valid (i.e. in the case of a decommissioned node), resulting in `undefined` and surfacing outdated node information. This change ensures that when we encounter such occurrences, we avoid displaying them in the console. Release note (bug fix): Avoid displaying `undefined` regions on the databases pages. --- .../cluster-ui/src/databases/util.spec.ts | 24 +++++++------------ .../cluster-ui/src/databases/util.ts | 4 ++++ .../databaseDetailsPage/redux.spec.ts | 4 ++-- .../databases/databaseTablePage/redux.spec.ts | 2 +- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/pkg/ui/workspaces/cluster-ui/src/databases/util.spec.ts b/pkg/ui/workspaces/cluster-ui/src/databases/util.spec.ts index 5a993ebd7088..25190598f443 100644 --- a/pkg/ui/workspaces/cluster-ui/src/databases/util.spec.ts +++ b/pkg/ui/workspaces/cluster-ui/src/databases/util.spec.ts @@ -25,7 +25,7 @@ describe("Getting nodes by region string", () => { "3": "region3", }; const result = getNodesByRegionString(nodes, regions, false); - assert.deepStrictEqual(result, `region1(n1), region2(n2), region3(n3)`); + expect(result).toEqual(`region1(n1), region2(n2), region3(n3)`); }); it("when all nodes same region", () => { @@ -36,7 +36,7 @@ describe("Getting nodes by region string", () => { "3": "region1", }; const result = getNodesByRegionString(nodes, regions, false); - assert.deepStrictEqual(result, `region1(n1,n2,n3)`); + expect(result).toEqual(`region1(n1,n2,n3)`); }); it("when some nodes different regions", () => { @@ -47,14 +47,14 @@ describe("Getting nodes by region string", () => { "3": "region2", }; const result = getNodesByRegionString(nodes, regions, false); - assert.deepStrictEqual(result, `region1(n1,n2), region2(n3)`); + expect(result).toEqual(`region1(n1,n2), region2(n3)`); }); it("when region map is empty", () => { const nodes = [1, 2, 3]; const regions = {}; const result = getNodesByRegionString(nodes, regions, false); - assert.deepStrictEqual(result, `undefined(n1,n2,n3)`); + expect(result).toEqual(""); }); it("when nodes are empty", () => { @@ -65,7 +65,7 @@ describe("Getting nodes by region string", () => { "3": "region2", }; const result = getNodesByRegionString(nodes, regions, false); - assert.deepStrictEqual(result, ""); + expect(result).toEqual(""); }); }); }); @@ -74,19 +74,13 @@ describe("Normalize privileges", () => { it("sorts correctly when input is disordered", () => { const privs = ["CREATE", "DELETE", "UPDATE", "ALL", "GRANT"]; const result = normalizePrivileges(privs); - assert.deepStrictEqual(result, [ - "ALL", - "CREATE", - "GRANT", - "UPDATE", - "DELETE", - ]); + expect(result).toEqual(["ALL", "CREATE", "GRANT", "UPDATE", "DELETE"]); }); it("removes duplicates", () => { const privs = ["CREATE", "CREATE", "UPDATE", "ALL", "GRANT"]; const result = normalizePrivileges(privs); - assert.deepStrictEqual(result, ["ALL", "CREATE", "GRANT", "UPDATE"]); + expect(result).toEqual(["ALL", "CREATE", "GRANT", "UPDATE"]); }); }); @@ -94,12 +88,12 @@ describe("Normalize roles", () => { it("sorts correctly when input is disordered", () => { const roles = ["public", "root", "admin"]; const result = normalizeRoles(roles); - assert.deepStrictEqual(result, ["root", "admin", "public"]); + expect(result).toEqual(["root", "admin", "public"]); }); it("removes duplicates", () => { const roles = ["public", "admin", "admin"]; const result = normalizeRoles(roles); - assert.deepStrictEqual(result, ["admin", "public"]); + expect(result).toEqual(["admin", "public"]); }); }); diff --git a/pkg/ui/workspaces/cluster-ui/src/databases/util.ts b/pkg/ui/workspaces/cluster-ui/src/databases/util.ts index c7cbd9ad62aa..5d82092f82f8 100644 --- a/pkg/ui/workspaces/cluster-ui/src/databases/util.ts +++ b/pkg/ui/workspaces/cluster-ui/src/databases/util.ts @@ -99,6 +99,10 @@ export function createNodesByRegionMap( ): Record { const nodesByRegionMap: Record = {}; nodes.forEach((node: number) => { + // If the node's region doesn't exist skip it. + if (nodeRegions[node.toString()] == null) { + return; + } const region: string = nodeRegions[node.toString()]; if (nodesByRegionMap[region] == null) { nodesByRegionMap[region] = []; diff --git a/pkg/ui/workspaces/db-console/src/views/databases/databaseDetailsPage/redux.spec.ts b/pkg/ui/workspaces/db-console/src/views/databases/databaseDetailsPage/redux.spec.ts index 79475c7aed61..7ea7e3564b4b 100644 --- a/pkg/ui/workspaces/db-console/src/views/databases/databaseDetailsPage/redux.spec.ts +++ b/pkg/ui/workspaces/db-console/src/views/databases/databaseDetailsPage/redux.spec.ts @@ -374,7 +374,7 @@ describe("Database Details Page", function () { replicationSizeInBytes: 100, rangeCount: 400, nodes: [1, 2, 3], - nodesByRegionString: "undefined(n1,n2,n3)", + nodesByRegionString: "", }, }); @@ -397,7 +397,7 @@ describe("Database Details Page", function () { replicationSizeInBytes: 10, rangeCount: 50, nodes: [1, 2, 3, 4, 5], - nodesByRegionString: "undefined(n1,n2,n3,n4,n5)", + nodesByRegionString: "", }, }); }); diff --git a/pkg/ui/workspaces/db-console/src/views/databases/databaseTablePage/redux.spec.ts b/pkg/ui/workspaces/db-console/src/views/databases/databaseTablePage/redux.spec.ts index d20ca7285df8..bc2efe74922c 100644 --- a/pkg/ui/workspaces/db-console/src/views/databases/databaseTablePage/redux.spec.ts +++ b/pkg/ui/workspaces/db-console/src/views/databases/databaseTablePage/redux.spec.ts @@ -287,7 +287,7 @@ describe("Database Table Page", function () { totalBytes: 45, sizeInBytes: 23, rangeCount: 56, - nodesByRegionString: "undefined(n1,n2,n3,n4,n5)", + nodesByRegionString: "", }); });