Skip to content

Commit

Permalink
cluster-ui: skip undefined regions on database pages
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Thomas Hardy committed Sep 15, 2023
1 parent ec7180f commit 52385a8
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 18 deletions.
24 changes: 9 additions & 15 deletions pkg/ui/workspaces/cluster-ui/src/databases/util.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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", () => {
Expand All @@ -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", () => {
Expand All @@ -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", () => {
Expand All @@ -65,7 +65,7 @@ describe("Getting nodes by region string", () => {
"3": "region2",
};
const result = getNodesByRegionString(nodes, regions, false);
assert.deepStrictEqual(result, "");
expect(result).toEqual("");
});
});
});
Expand All @@ -74,32 +74,26 @@ 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"]);
});
});

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"]);
});
});
4 changes: 4 additions & 0 deletions pkg/ui/workspaces/cluster-ui/src/databases/util.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ export function createNodesByRegionMap(
): Record<string, number[]> {
const nodesByRegionMap: Record<string, number[]> = {};
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] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ describe("Database Details Page", function () {
live_percentage: 0.5,
},
nodes: [1, 2, 3],
nodesByRegionString: "undefined(n1,n2,n3)",
nodesByRegionString: "",
},
});

Expand Down Expand Up @@ -437,7 +437,7 @@ describe("Database Details Page", function () {
approximate_disk_bytes: 10,
},
nodes: [1, 2, 3, 4, 5],
nodesByRegionString: "undefined(n1,n2,n3,n4,n5)",
nodesByRegionString: "",
},
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ describe("Database Table Page", function () {
totalBytes: 45,
sizeInBytes: 23,
rangeCount: 56,
nodesByRegionString: "undefined(n1,n2,n3,n4,n5)",
nodesByRegionString: "",
});
});

Expand Down

0 comments on commit 52385a8

Please sign in to comment.