From 8f0cf8afcebf586cb053995eb0f56021a38a54df Mon Sep 17 00:00:00 2001 From: Andrew Henry Date: Tue, 11 Feb 2025 15:19:37 -0800 Subject: [PATCH] V2, restore short-circuit eval --- src/plugins/condition/Condition.js | 36 +++++++++++-------- src/plugins/condition/ConditionManager.js | 35 +++++++----------- .../criterion/AllTelemetryCriterion.js | 16 ++++++--- 3 files changed, 45 insertions(+), 42 deletions(-) diff --git a/src/plugins/condition/Condition.js b/src/plugins/condition/Condition.js index 2bd1bd8640..a9f6e1828a 100644 --- a/src/plugins/condition/Condition.js +++ b/src/plugins/condition/Condition.js @@ -44,50 +44,56 @@ import { getLatestTimestamp } from './utils/time.js'; * } */ export default class Condition extends EventEmitter { + #definition; /** * Manages criteria and emits the result of - true or false - based on criteria evaluated. * @constructor - * @param conditionConfiguration: {id: uuid,trigger: enum, criteria: Array of {id: uuid, operation: enum, input: Array, metaDataKey: string, key: {domainObject.identifier} } + * @param definition: {id: uuid,trigger: enum, criteria: Array of {id: uuid, operation: enum, input: Array, metaDataKey: string, key: {domainObject.identifier} } * @param openmct * @param conditionManager */ - constructor(conditionConfiguration, openmct, conditionManager) { + constructor(definition, openmct, conditionManager) { super(); this.openmct = openmct; this.conditionManager = conditionManager; - this.id = conditionConfiguration.id; this.criteria = []; this.result = undefined; this.timeSystems = this.openmct.time.getAllTimeSystems(); - if (conditionConfiguration.configuration.criteria) { - this.createCriteria(conditionConfiguration.configuration.criteria); + this.#definition = definition; + + if (definition.configuration.criteria) { + this.createCriteria(definition.configuration.criteria); } - this.trigger = conditionConfiguration.configuration.trigger; + this.trigger = definition.configuration.trigger; this.summary = ''; this.handleCriterionUpdated = this.handleCriterionUpdated.bind(this); this.handleOldTelemetryCriterion = this.handleOldTelemetryCriterion.bind(this); this.handleTelemetryStaleness = this.handleTelemetryStaleness.bind(this); } + get id() { + return this.#definition.id; + } + get configuration() { + return this.#definition.configuration; + } - updateResult(latestDataTable) { + updateResult(latestDataTable, telemetryIdThatChanged) { if (!latestDataTable) { console.log('no data received'); return; } - const hasNoTelemetry = this.hasNoTelemetry(); - // if all the criteria in this condition have no telemetry, we want to force the condition result to evaluate - //if (this.hasNoTelemetry() || this.isTelemetryUsed(latestDataTable.id)) { + if (this.hasNoTelemetry() || this.isTelemetryUsed(telemetryIdThatChanged)) { this.criteria.forEach((criterion) => { if (this.isAnyOrAllTelemetry(criterion)) { criterion.updateResult(latestDataTable, this.conditionManager.telemetryObjects); } else { const relevantDatum = latestDataTable.get(criterion.telemetryObjectIdAsString); - if (relevantDatum !== undefined){ + if (relevantDatum !== undefined) { criterion.updateResult(relevantDatum); } } @@ -97,7 +103,7 @@ export default class Condition extends EventEmitter { this.criteria.map((criterion) => criterion.result), this.trigger ); - //} + } } isAnyOrAllTelemetry(criterion) { @@ -105,9 +111,11 @@ export default class Condition extends EventEmitter { } hasNoTelemetry() { - return this.criteria.every((criterion) => { - return !this.isAnyOrAllTelemetry(criterion) && criterion.telemetry === ''; + const usesSomeTelemetry = this.criteria.some((criterion) => { + return this.isAnyOrAllTelemetry(criterion) || criterion.telemetry !== ''; }); + + return !usesSomeTelemetry; } isTelemetryUsed(id) { diff --git a/src/plugins/condition/ConditionManager.js b/src/plugins/condition/ConditionManager.js index 0daefd0789..2c90e852e3 100644 --- a/src/plugins/condition/ConditionManager.js +++ b/src/plugins/condition/ConditionManager.js @@ -306,22 +306,6 @@ export default class ConditionManager extends EventEmitter { this.persistConditions(); } - getCurrentCondition() { - const conditionCollection = this.conditionSetDomainObject.configuration.conditionCollection; - let currentCondition = conditionCollection[conditionCollection.length - 1]; - - for (let i = 0; i < conditionCollection.length - 1; i++) { - const condition = this.findConditionById(conditionCollection[i].id); - if (condition.result) { - //first condition to be true wins - currentCondition = conditionCollection[i]; - break; - } - } - - return currentCondition; - } - getCurrentConditionLAD(conditionResults) { const conditionCollection = this.conditionSetDomainObject.configuration.conditionCollection; let currentCondition = conditionCollection[conditionCollection.length - 1]; @@ -419,22 +403,27 @@ export default class ConditionManager extends EventEmitter { this.#latestDataTable.set(normalizedDatum.id, normalizedDatum); if (this.shouldEvaluateNewTelemetry(currentTimestamp)) { - this.updateConditionResults(); - this.updateCurrentCondition(timestamp); + const matchingCondition = this.updateConditionResults(normalizedDatum.id); + this.updateCurrentCondition(timestamp, matchingCondition); } } - updateConditionResults() { + updateConditionResults(keyStringForUpdatedTelemetryObject) { //We want to stop when the first condition evaluates to true. - this.conditions.some((condition) => { - condition.updateResult(this.#latestDataTable); + const matchingCondition = this.conditions.find((condition) => { + condition.updateResult(this.#latestDataTable, keyStringForUpdatedTelemetryObject); return condition.result === true; }); + + return matchingCondition; } - updateCurrentCondition(timestamp) { - const currentCondition = this.getCurrentCondition(); + updateCurrentCondition(timestamp, matchingCondition) { + const conditionCollection = this.conditionSetDomainObject.configuration.conditionCollection; + const defaultCondition = conditionCollection[conditionCollection.length - 1]; + + const currentCondition = matchingCondition || defaultCondition; this.emit( 'conditionSetResultUpdated', diff --git a/src/plugins/condition/criterion/AllTelemetryCriterion.js b/src/plugins/condition/criterion/AllTelemetryCriterion.js index 3dc497dd07..67ab770f0f 100644 --- a/src/plugins/condition/criterion/AllTelemetryCriterion.js +++ b/src/plugins/condition/criterion/AllTelemetryCriterion.js @@ -181,13 +181,19 @@ export default class AllTelemetryCriterion extends TelemetryCriterion { if (validatedData && !this.isStalenessCheck()) { if (this.isOldCheck()) { - if (this.ageCheck?.[validatedData.id]) { - this.ageCheck[validatedData.id].update(validatedData); - } + Object.keys(this.telemetryDataCache).forEach((objectIdKeystring) => { + if (this.ageCheck?.[objectIdKeystring]) { + this.ageCheck[objectIdKeystring].update(validatedData[objectIdKeystring]); + } - this.telemetryDataCache[validatedData.id] = false; + this.telemetryDataCache[objectIdKeystring] = false; + }); } else { - this.telemetryDataCache[validatedData.id] = this.computeResult(validatedData); + Object.keys(this.telemetryDataCache).forEach((objectIdKeystring) => { + this.telemetryDataCache[objectIdKeystring] = this.computeResult( + validatedData[objectIdKeystring] + ); + }); } }