V2, restore short-circuit eval

This commit is contained in:
Andrew Henry 2025-02-11 15:19:37 -08:00
parent ddf2bd5e66
commit bc6a828e9e
3 changed files with 45 additions and 42 deletions

View File

@ -44,50 +44,56 @@ import { getLatestTimestamp } from './utils/time.js';
* } * }
*/ */
export default class Condition extends EventEmitter { export default class Condition extends EventEmitter {
#definition;
/** /**
* Manages criteria and emits the result of - true or false - based on criteria evaluated. * Manages criteria and emits the result of - true or false - based on criteria evaluated.
* @constructor * @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 openmct
* @param conditionManager * @param conditionManager
*/ */
constructor(conditionConfiguration, openmct, conditionManager) { constructor(definition, openmct, conditionManager) {
super(); super();
this.openmct = openmct; this.openmct = openmct;
this.conditionManager = conditionManager; this.conditionManager = conditionManager;
this.id = conditionConfiguration.id;
this.criteria = []; this.criteria = [];
this.result = undefined; this.result = undefined;
this.timeSystems = this.openmct.time.getAllTimeSystems(); this.timeSystems = this.openmct.time.getAllTimeSystems();
if (conditionConfiguration.configuration.criteria) { this.#definition = definition;
this.createCriteria(conditionConfiguration.configuration.criteria);
if (definition.configuration.criteria) {
this.createCriteria(definition.configuration.criteria);
} }
this.trigger = conditionConfiguration.configuration.trigger; this.trigger = definition.configuration.trigger;
this.summary = ''; this.summary = '';
this.handleCriterionUpdated = this.handleCriterionUpdated.bind(this); this.handleCriterionUpdated = this.handleCriterionUpdated.bind(this);
this.handleOldTelemetryCriterion = this.handleOldTelemetryCriterion.bind(this); this.handleOldTelemetryCriterion = this.handleOldTelemetryCriterion.bind(this);
this.handleTelemetryStaleness = this.handleTelemetryStaleness.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) { if (!latestDataTable) {
console.log('no data received'); console.log('no data received');
return; 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 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) => { this.criteria.forEach((criterion) => {
if (this.isAnyOrAllTelemetry(criterion)) { if (this.isAnyOrAllTelemetry(criterion)) {
criterion.updateResult(latestDataTable, this.conditionManager.telemetryObjects); criterion.updateResult(latestDataTable, this.conditionManager.telemetryObjects);
} else { } else {
const relevantDatum = latestDataTable.get(criterion.telemetryObjectIdAsString); const relevantDatum = latestDataTable.get(criterion.telemetryObjectIdAsString);
if (relevantDatum !== undefined){ if (relevantDatum !== undefined) {
criterion.updateResult(relevantDatum); criterion.updateResult(relevantDatum);
} }
} }
@ -97,7 +103,7 @@ export default class Condition extends EventEmitter {
this.criteria.map((criterion) => criterion.result), this.criteria.map((criterion) => criterion.result),
this.trigger this.trigger
); );
//} }
} }
isAnyOrAllTelemetry(criterion) { isAnyOrAllTelemetry(criterion) {
@ -105,9 +111,11 @@ export default class Condition extends EventEmitter {
} }
hasNoTelemetry() { hasNoTelemetry() {
return this.criteria.every((criterion) => { const usesSomeTelemetry = this.criteria.some((criterion) => {
return !this.isAnyOrAllTelemetry(criterion) && criterion.telemetry === ''; return this.isAnyOrAllTelemetry(criterion) || criterion.telemetry !== '';
}); });
return !usesSomeTelemetry;
} }
isTelemetryUsed(id) { isTelemetryUsed(id) {

View File

@ -306,22 +306,6 @@ export default class ConditionManager extends EventEmitter {
this.persistConditions(); 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) { getCurrentConditionLAD(conditionResults) {
const conditionCollection = this.conditionSetDomainObject.configuration.conditionCollection; const conditionCollection = this.conditionSetDomainObject.configuration.conditionCollection;
let currentCondition = conditionCollection[conditionCollection.length - 1]; let currentCondition = conditionCollection[conditionCollection.length - 1];
@ -419,22 +403,27 @@ export default class ConditionManager extends EventEmitter {
this.#latestDataTable.set(normalizedDatum.id, normalizedDatum); this.#latestDataTable.set(normalizedDatum.id, normalizedDatum);
if (this.shouldEvaluateNewTelemetry(currentTimestamp)) { if (this.shouldEvaluateNewTelemetry(currentTimestamp)) {
this.updateConditionResults(); const matchingCondition = this.updateConditionResults(normalizedDatum.id);
this.updateCurrentCondition(timestamp); this.updateCurrentCondition(timestamp, matchingCondition);
} }
} }
updateConditionResults() { updateConditionResults(keyStringForUpdatedTelemetryObject) {
//We want to stop when the first condition evaluates to true. //We want to stop when the first condition evaluates to true.
this.conditions.some((condition) => { const matchingCondition = this.conditions.find((condition) => {
condition.updateResult(this.#latestDataTable); condition.updateResult(this.#latestDataTable, keyStringForUpdatedTelemetryObject);
return condition.result === true; return condition.result === true;
}); });
return matchingCondition;
} }
updateCurrentCondition(timestamp) { updateCurrentCondition(timestamp, matchingCondition) {
const currentCondition = this.getCurrentCondition(); const conditionCollection = this.conditionSetDomainObject.configuration.conditionCollection;
const defaultCondition = conditionCollection[conditionCollection.length - 1];
const currentCondition = matchingCondition || defaultCondition;
this.emit( this.emit(
'conditionSetResultUpdated', 'conditionSetResultUpdated',

View File

@ -181,13 +181,19 @@ export default class AllTelemetryCriterion extends TelemetryCriterion {
if (validatedData && !this.isStalenessCheck()) { if (validatedData && !this.isStalenessCheck()) {
if (this.isOldCheck()) { if (this.isOldCheck()) {
if (this.ageCheck?.[validatedData.id]) { Object.keys(this.telemetryDataCache).forEach((objectIdKeystring) => {
this.ageCheck[validatedData.id].update(validatedData); if (this.ageCheck?.[objectIdKeystring]) {
} this.ageCheck[objectIdKeystring].update(validatedData[objectIdKeystring]);
}
this.telemetryDataCache[validatedData.id] = false; this.telemetryDataCache[objectIdKeystring] = false;
});
} else { } else {
this.telemetryDataCache[validatedData.id] = this.computeResult(validatedData); Object.keys(this.telemetryDataCache).forEach((objectIdKeystring) => {
this.telemetryDataCache[objectIdKeystring] = this.computeResult(
validatedData[objectIdKeystring]
);
});
} }
} }