Merge pull request #148 from prymitive/speed-up-updates

refactor(ui): speed up updates with large number of alerts
This commit is contained in:
Łukasz Mierzwa
2018-10-14 13:41:15 +01:00
committed by GitHub
2 changed files with 74 additions and 7 deletions

View File

@@ -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" &&

View File

@@ -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" }
});
});
});