diff --git a/ui/app/services/stats-trackers-registry.js b/ui/app/services/stats-trackers-registry.js new file mode 100644 index 000000000..81a8540b0 --- /dev/null +++ b/ui/app/services/stats-trackers-registry.js @@ -0,0 +1,43 @@ +import Service, { inject as service } from '@ember/service'; +import { LRUMap } from 'lru_map'; +import NodeStatsTracker from 'nomad-ui/utils/classes/node-stats-tracker'; +import AllocationStatsTracker from 'nomad-ui/utils/classes/allocation-stats-tracker'; + +// An unbounded number of stat trackers is a great way to gobble up all the memory +// on a machine. This max number is unscientific, but aims to balance losing +// stat trackers a user is likely to return to with preventing gc from freeing +// memory occupied by stat trackers a user is likely to no longer care about +const MAX_STAT_TRACKERS = 10; +let registry; + +export default Service.extend({ + token: service(), + + init() { + // The LRUMap limits the number of trackers tracked by making room for + // new entries beyond the limit by removing the least recently used entry. + registry = new LRUMap(MAX_STAT_TRACKERS); + }, + + getTracker(resource) { + if (!resource) return; + + const type = resource && resource.constructor.modelName; + const key = `${type}:${resource.get('id')}`; + + const cachedTracker = registry.get(key); + if (cachedTracker) return cachedTracker; + + const Constructor = type === 'node' ? NodeStatsTracker : AllocationStatsTracker; + const resourceProp = type === 'node' ? 'node' : 'allocation'; + + const tracker = Constructor.create({ + fetch: url => this.get('token').authorizedRequest(url), + [resourceProp]: resource, + }); + + registry.set(key, tracker); + + return tracker; + }, +});