mirror of
https://github.com/nasa/openmct.git
synced 2024-12-19 05:07:52 +00:00
[Greedy LAD] Add new functionality for Latest Available Data views (#6432)
* adding greedyLAD logic to telemetry collections --------- Co-authored-by: Andrew Henry <akhenry@gmail.com>
This commit is contained in:
parent
25c0dab346
commit
39463c515f
@ -29,6 +29,7 @@ import DefaultMetadataProvider from './DefaultMetadataProvider';
|
||||
import objectUtils from 'objectUtils';
|
||||
|
||||
export default class TelemetryAPI {
|
||||
#isGreedyLAD;
|
||||
|
||||
constructor(openmct) {
|
||||
this.openmct = openmct;
|
||||
@ -44,8 +45,8 @@ export default class TelemetryAPI {
|
||||
this.requestProviders = [];
|
||||
this.subscriptionProviders = [];
|
||||
this.valueFormatterCache = new WeakMap();
|
||||
|
||||
this.requestInterceptorRegistry = new TelemetryRequestInterceptorRegistry();
|
||||
this.#isGreedyLAD = true;
|
||||
}
|
||||
|
||||
abortAllRequests() {
|
||||
@ -226,6 +227,31 @@ export default class TelemetryAPI {
|
||||
return modifiedRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or set greedy LAD. For stategy "latest" telemetry in
|
||||
* realtime mode the start bound will be ignored if true and
|
||||
* there is no new data to replace the existing data.
|
||||
* defaults to true
|
||||
*
|
||||
* To turn off greedy LAD:
|
||||
* openmct.telemetry.greedyLAD(false);
|
||||
*
|
||||
* @method greedyLAD
|
||||
* @returns {boolean} if greedyLAD is active or not
|
||||
* @memberof module:openmct.TelemetryAPI#
|
||||
*/
|
||||
greedyLAD(isGreedy) {
|
||||
if (arguments.length > 0) {
|
||||
if (isGreedy !== true && isGreedy !== false) {
|
||||
throw new Error('Error setting greedyLAD. Greedy LAD only accepts true or false values');
|
||||
}
|
||||
|
||||
this.#isGreedyLAD = isGreedy;
|
||||
}
|
||||
|
||||
return this.#isGreedyLAD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request telemetry collection for a domain object.
|
||||
* The `options` argument allows you to specify filters
|
||||
|
@ -30,8 +30,8 @@ export default class TelemetryCollection extends EventEmitter {
|
||||
/**
|
||||
* Creates a Telemetry Collection
|
||||
*
|
||||
* @param {object} openmct - Openm MCT
|
||||
* @param {object} domainObject - Domain Object to user for telemetry collection
|
||||
* @param {OpenMCT} openmct - Open MCT
|
||||
* @param {module:openmct.DomainObject} domainObject - Domain Object to use for telemetry collection
|
||||
* @param {object} options - Any options passed in for request/subscribe
|
||||
*/
|
||||
constructor(openmct, domainObject, options) {
|
||||
@ -50,6 +50,7 @@ export default class TelemetryCollection extends EventEmitter {
|
||||
this.lastBounds = undefined;
|
||||
this.requestAbort = undefined;
|
||||
this.isStrategyLatest = this.options.strategy === 'latest';
|
||||
this.dataOutsideTimeBounds = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -184,6 +185,7 @@ export default class TelemetryCollection extends EventEmitter {
|
||||
let afterEndOfBounds;
|
||||
let added = [];
|
||||
let addedIndices = [];
|
||||
let hasDataBeforeStartBound = false;
|
||||
|
||||
// loop through, sort and dedupe
|
||||
for (let datum of data) {
|
||||
@ -191,7 +193,7 @@ export default class TelemetryCollection extends EventEmitter {
|
||||
beforeStartOfBounds = parsedValue < this.lastBounds.start;
|
||||
afterEndOfBounds = parsedValue > this.lastBounds.end;
|
||||
|
||||
if (!afterEndOfBounds && !beforeStartOfBounds) {
|
||||
if (!afterEndOfBounds && (!beforeStartOfBounds || (this.isStrategyLatest && this.openmct.telemetry.greedyLAD()))) {
|
||||
let isDuplicate = false;
|
||||
let startIndex = this._sortedIndex(datum);
|
||||
let endIndex = undefined;
|
||||
@ -218,6 +220,10 @@ export default class TelemetryCollection extends EventEmitter {
|
||||
this.boundedTelemetry.splice(index, 0, datum);
|
||||
addedIndices.push(index);
|
||||
added.push(datum);
|
||||
|
||||
if (!hasDataBeforeStartBound && beforeStartOfBounds) {
|
||||
hasDataBeforeStartBound = true;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (afterEndOfBounds) {
|
||||
@ -226,12 +232,18 @@ export default class TelemetryCollection extends EventEmitter {
|
||||
}
|
||||
|
||||
if (added.length) {
|
||||
// if latest strategy is requested, we need to check if the value is the latest unmitted value
|
||||
// if latest strategy is requested, we need to check if the value is the latest unemitted value
|
||||
if (this.isStrategyLatest) {
|
||||
this.boundedTelemetry = [this.boundedTelemetry[this.boundedTelemetry.length - 1]];
|
||||
|
||||
// if true, then this value has yet to be emitted
|
||||
if (this.boundedTelemetry[0] !== latestBoundedDatum) {
|
||||
if (hasDataBeforeStartBound) {
|
||||
this._handleDataOutsideBounds();
|
||||
} else {
|
||||
this._handleDataInsideBounds();
|
||||
}
|
||||
|
||||
this.emit('add', this.boundedTelemetry);
|
||||
}
|
||||
} else {
|
||||
@ -294,6 +306,17 @@ export default class TelemetryCollection extends EventEmitter {
|
||||
let added = [];
|
||||
let testDatum = {};
|
||||
|
||||
if (endChanged) {
|
||||
testDatum[this.timeKey] = bounds.end;
|
||||
// Calculate the new index of the last item in bounds
|
||||
endIndex = _.sortedLastIndexBy(
|
||||
this.futureBuffer,
|
||||
testDatum,
|
||||
datum => this.parseTime(datum)
|
||||
);
|
||||
added = this.futureBuffer.splice(0, endIndex);
|
||||
}
|
||||
|
||||
if (startChanged) {
|
||||
testDatum[this.timeKey] = bounds.start;
|
||||
|
||||
@ -307,20 +330,19 @@ export default class TelemetryCollection extends EventEmitter {
|
||||
);
|
||||
discarded = this.boundedTelemetry.splice(0, startIndex);
|
||||
} else if (this.parseTime(testDatum) > this.parseTime(this.boundedTelemetry[0])) {
|
||||
discarded = this.boundedTelemetry;
|
||||
this.boundedTelemetry = [];
|
||||
}
|
||||
}
|
||||
// if greedyLAD is active and there is no new data to replace, don't discard
|
||||
const isGreedyLAD = this.openmct.telemetry.greedyLAD();
|
||||
const shouldRemove = (!isGreedyLAD || (isGreedyLAD && added.length > 0));
|
||||
|
||||
if (endChanged) {
|
||||
testDatum[this.timeKey] = bounds.end;
|
||||
// Calculate the new index of the last item in bounds
|
||||
endIndex = _.sortedLastIndexBy(
|
||||
this.futureBuffer,
|
||||
testDatum,
|
||||
datum => this.parseTime(datum)
|
||||
);
|
||||
added = this.futureBuffer.splice(0, endIndex);
|
||||
if (shouldRemove) {
|
||||
discarded = this.boundedTelemetry;
|
||||
this.boundedTelemetry = [];
|
||||
// since it IS strategy latest, we can assume there will be at least 1 datum
|
||||
// unless no data was returned in the first request, we need to account for that
|
||||
} else if (this.boundedTelemetry.length === 1) {
|
||||
this._handleDataOutsideBounds();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (discarded.length > 0) {
|
||||
@ -331,6 +353,8 @@ export default class TelemetryCollection extends EventEmitter {
|
||||
if (!this.isStrategyLatest) {
|
||||
this.boundedTelemetry = [...this.boundedTelemetry, ...added];
|
||||
} else {
|
||||
this._handleDataInsideBounds();
|
||||
|
||||
added = [added[added.length - 1]];
|
||||
this.boundedTelemetry = added;
|
||||
}
|
||||
@ -345,6 +369,20 @@ export default class TelemetryCollection extends EventEmitter {
|
||||
|
||||
}
|
||||
|
||||
_handleDataInsideBounds() {
|
||||
if (this.dataOutsideTimeBounds) {
|
||||
this.dataOutsideTimeBounds = false;
|
||||
this.emit('dataInsideTimeBounds');
|
||||
}
|
||||
}
|
||||
|
||||
_handleDataOutsideBounds() {
|
||||
if (!this.dataOutsideTimeBounds) {
|
||||
this.dataOutsideTimeBounds = true;
|
||||
this.emit('dataOutsideTimeBounds');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* whenever the time system is updated need to update related values in
|
||||
* the Telemetry Collection and reset the telemetry collection
|
||||
|
Loading…
Reference in New Issue
Block a user