Merge pull request #1698 from balena-os/optimize-current-state-filtering

Optimize current state filtering
This commit is contained in:
bulldozer-balena[bot] 2021-05-12 07:50:05 +00:00 committed by GitHub
commit bd2363c0b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 74 deletions

View File

@ -108,25 +108,25 @@ const getStateDiff = (): DeviceStatus => {
}
const diff = {
local: _(stateForReport.local)
.omitBy((val, key: keyof DeviceStatus['local']) =>
_.isEqual(lastReportedLocal[key], val),
)
.omit(INTERNAL_STATE_KEYS)
.value(),
dependent: _(stateForReport.dependent)
.omitBy((val, key: keyof DeviceStatus['dependent']) =>
local: _.omitBy(
stateForReport.local,
(val, key: keyof NonNullable<DeviceStatus['local']>) =>
INTERNAL_STATE_KEYS.includes(key) ||
_.isEqual(lastReportedLocal[key], val) ||
!sysInfo.isSignificantChange(
key,
lastReportedLocal[key] as number,
val as number,
),
),
dependent: _.omitBy(
stateForReport.dependent,
(val, key: keyof DeviceStatus['dependent']) =>
INTERNAL_STATE_KEYS.includes(key) ||
_.isEqual(lastReportedDependent[key], val),
)
.omit(INTERNAL_STATE_KEYS)
.value(),
),
};
const toOmit: string[] = sysInfo.filterNonSignificantChanges(
lastReportedLocal as sysInfo.SystemInfo,
stateForReport.local as sysInfo.SystemInfo,
);
diff.local = _.omit(diff.local, toOmit);
return _.omitBy(diff, _.isEmpty);
};

View File

@ -120,28 +120,22 @@ const significantChange: { [key in keyof SystemInfo]?: number } = {
memory_usage: 10,
};
export function filterNonSignificantChanges(
past: Partial<SystemInfo>,
current: SystemInfo,
): Array<keyof SystemInfo> {
return Object.keys(
_.omitBy(current, (value, key: keyof SystemInfo) => {
// If we didn't have a value for this in the past, include it
if (past[key] == null) {
return true;
}
const bucketSize = significantChange[key];
// If we don't have any requirements on this value, include it
if (bucketSize == null) {
return true;
}
export function isSignificantChange(
key: string,
past: number | undefined,
current: number,
): boolean {
// If we didn't have a value for this in the past, include it
if (past == null) {
return true;
}
const bucketSize = significantChange[key as keyof SystemInfo];
// If we don't have any requirements on this value, include it
if (bucketSize == null) {
return true;
}
return (
Math.floor((value as number) / bucketSize) !==
Math.floor((past[key] as number) / bucketSize)
);
}),
) as Array<keyof SystemInfo>;
return Math.floor(current / bucketSize) !== Math.floor(past / bucketSize);
}
function bytesToMb(bytes: number) {

View File

@ -40,7 +40,9 @@ export interface DeviceStatus {
};
} & DeviceReportFields;
// TODO: Type the dependent entry correctly
dependent?: any;
dependent?: {
[key: string]: any;
};
commit?: string;
}

View File

@ -24,55 +24,39 @@ describe('System information', async () => {
describe('Delta-based filtering', () => {
it('should correctly filter cpu usage', () => {
expect(
sysInfo.filterNonSignificantChanges({ cpu_usage: 21 }, {
cpu_usage: 20,
} as sysInfo.SystemInfo),
).to.deep.equal(['cpu_usage']);
expect(sysInfo.isSignificantChange('cpu_usage', 21, 20)).to.equal(false);
expect(
sysInfo.filterNonSignificantChanges({ cpu_usage: 10 }, {
cpu_usage: 20,
} as sysInfo.SystemInfo),
).to.deep.equal([]);
expect(sysInfo.isSignificantChange('cpu_usage', 10, 20)).to.equal(true);
});
it('should correctly filter cpu temperature', () => {
expect(
sysInfo.filterNonSignificantChanges({ cpu_temp: 21 }, {
cpu_temp: 22,
} as sysInfo.SystemInfo),
).to.deep.equal(['cpu_temp']);
expect(sysInfo.isSignificantChange('cpu_temp', 21, 22)).to.equal(false);
expect(
sysInfo.filterNonSignificantChanges({ cpu_temp: 10 }, {
cpu_temp: 20,
} as sysInfo.SystemInfo),
).to.deep.equal([]);
expect(sysInfo.isSignificantChange('cpu_temp', 10, 20)).to.equal(true);
});
it('should correctly filter memory usage', () => {
expect(
sysInfo.filterNonSignificantChanges({ memory_usage: 21 }, {
memory_usage: 22,
} as sysInfo.SystemInfo),
).to.deep.equal(['memory_usage']);
expect(sysInfo.isSignificantChange('memory_usage', 21, 22)).to.equal(
false,
);
expect(
sysInfo.filterNonSignificantChanges({ memory_usage: 10 }, {
memory_usage: 20,
} as sysInfo.SystemInfo),
).to.deep.equal([]);
expect(sysInfo.isSignificantChange('memory_usage', 10, 20)).to.equal(
true,
);
});
it('should not filter if we didnt have a past value', () => {
expect(sysInfo.isSignificantChange('cpu_usage', undefined, 22)).to.equal(
true,
);
expect(sysInfo.isSignificantChange('cpu_temp', undefined, 10)).to.equal(
true,
);
expect(
sysInfo.filterNonSignificantChanges({}, {
memory_usage: 22,
cpu_usage: 10,
cpu_temp: 5,
} as sysInfo.SystemInfo),
).to.deep.equal([]);
sysInfo.isSignificantChange('memory_usage', undefined, 5),
).to.equal(true);
});
});