mirror of
https://github.com/prymitive/karma
synced 2026-05-05 03:16:51 +00:00
refactor(ui): speed up updates with large number of alerts
Comparing group dicts with large number of alerts is expensive, doing it per group and using hash checks will speed up updates, especially when alerts don't change often
This commit is contained in:
@@ -285,13 +285,7 @@ class AlertStore {
|
||||
|
||||
let updates = {};
|
||||
// update data dicts if they changed
|
||||
for (const key of [
|
||||
"colors",
|
||||
"counters",
|
||||
"groups",
|
||||
"silences",
|
||||
"upstreams"
|
||||
]) {
|
||||
for (const key of ["colors", "counters", "silences", "upstreams"]) {
|
||||
if (!equal(this.data[key], result[key])) {
|
||||
updates[key] = result[key];
|
||||
}
|
||||
@@ -300,6 +294,27 @@ class AlertStore {
|
||||
this.data = Object.assign(this.data, updates);
|
||||
}
|
||||
|
||||
// update groups, it can be huge so we have custom logic with cheaper
|
||||
// comparision logic running per group using content hashes from the API
|
||||
// response
|
||||
for (const key of Object.keys(result.groups)) {
|
||||
// set/update each group if:
|
||||
// * it's not yet stored in AlertStore
|
||||
// * it's stored but hash is different than in the API response
|
||||
if (
|
||||
!(key in this.data.groups) ||
|
||||
(key in this.data.groups &&
|
||||
result.groups[key].hash !== this.data.groups[key].hash)
|
||||
) {
|
||||
this.data.groups[key] = result.groups[key];
|
||||
}
|
||||
}
|
||||
for (const key of Object.keys(this.data.groups).filter(
|
||||
k => !(k in result.groups)
|
||||
)) {
|
||||
delete this.data.groups[key];
|
||||
}
|
||||
|
||||
// before storing new version check if we need to reload
|
||||
if (
|
||||
this.info.version !== "unknown" &&
|
||||
|
||||
@@ -333,4 +333,56 @@ describe("AlertStore.fetch", () => {
|
||||
await expect(store.fetch()).resolves.toBeUndefined();
|
||||
expect(store.info.upgradeNeeded).toBe(true);
|
||||
});
|
||||
|
||||
it("adds new groups to the store after fetch", () => {
|
||||
const response = EmptyAPIResponse();
|
||||
response.groups = { foo: "foo", bar: "bar" };
|
||||
const store = new AlertStore(["label=value"]);
|
||||
store.parseAPIResponse(response);
|
||||
expect(Object.keys(store.data.groups)).toHaveLength(2);
|
||||
expect(store.data.groups).toMatchObject({ foo: "foo", bar: "bar" });
|
||||
});
|
||||
|
||||
it("is no-op for groups that didn't change", () => {
|
||||
const store = new AlertStore(["label=value"]);
|
||||
store.data.groups = { foo: { hash: "foo" }, bar: { hash: "bar" } };
|
||||
|
||||
const response = EmptyAPIResponse();
|
||||
response.groups = { foo: { hash: "foo" }, bar: { hash: "bar" } };
|
||||
|
||||
store.parseAPIResponse(response);
|
||||
expect(Object.keys(store.data.groups)).toHaveLength(2);
|
||||
expect(store.data.groups).toMatchObject({
|
||||
foo: { hash: "foo" },
|
||||
bar: { hash: "bar" }
|
||||
});
|
||||
});
|
||||
|
||||
it("removes old groups from the store after fetch", () => {
|
||||
const store = new AlertStore(["label=value"]);
|
||||
store.data.groups = { foo: "foo", delete: "me", bar: "bar" };
|
||||
expect(Object.keys(store.data.groups)).toHaveLength(3);
|
||||
|
||||
const response = EmptyAPIResponse();
|
||||
response.groups = { foo: "foo", bar: "bar" };
|
||||
|
||||
store.parseAPIResponse(response);
|
||||
expect(Object.keys(store.data.groups)).toHaveLength(2);
|
||||
expect(store.data.groups).toMatchObject({ foo: "foo", bar: "bar" });
|
||||
});
|
||||
|
||||
it("updates groups with new hash after fetch", () => {
|
||||
const store = new AlertStore(["label=value"]);
|
||||
store.data.groups = { foo: { hash: "foo" }, bar: { hash: "bar" } };
|
||||
|
||||
const response = EmptyAPIResponse();
|
||||
response.groups = { foo: { hash: "newFoo" }, bar: { hash: "newBar" } };
|
||||
|
||||
store.parseAPIResponse(response);
|
||||
expect(Object.keys(store.data.groups)).toHaveLength(2);
|
||||
expect(store.data.groups).toMatchObject({
|
||||
foo: { hash: "newFoo" },
|
||||
bar: { hash: "newBar" }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user