github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/ui/app/services/stats-trackers-registry.js (about)

     1  import { computed } from '@ember/object';
     2  import Service, { inject as service } from '@ember/service';
     3  import { LRUMap } from 'lru_map';
     4  import NodeStatsTracker from 'nomad-ui/utils/classes/node-stats-tracker';
     5  import AllocationStatsTracker from 'nomad-ui/utils/classes/allocation-stats-tracker';
     6  
     7  // An unbounded number of stat trackers is a great way to gobble up all the memory
     8  // on a machine. This max number is unscientific, but aims to balance losing
     9  // stat trackers a user is likely to return to with preventing gc from freeing
    10  // memory occupied by stat trackers a user is likely to no longer care about
    11  const MAX_STAT_TRACKERS = 10;
    12  let registry;
    13  
    14  const exists = (tracker, prop) =>
    15    tracker.get(prop) &&
    16    !tracker.get(prop).isDestroyed &&
    17    !tracker.get(prop).isDestroying;
    18  
    19  export default class StatsTrackersRegistryService extends Service {
    20    @service token;
    21  
    22    constructor() {
    23      super(...arguments);
    24  
    25      // The LRUMap limits the number of trackers tracked by making room for
    26      // new entries beyond the limit by removing the least recently used entry.
    27      registry = new LRUMap(MAX_STAT_TRACKERS);
    28    }
    29  
    30    // A read-only way of getting a reference to the registry.
    31    // Since this could be overwritten by a bad actor, it isn't
    32    // used in getTracker
    33    @computed
    34    get registryRef() {
    35      return registry;
    36    }
    37  
    38    getTracker(resource) {
    39      if (!resource) return;
    40  
    41      const type = resource && resource.constructor.modelName;
    42      const key = `${type}:${resource.get('id')}`;
    43      const Constructor =
    44        type === 'node' ? NodeStatsTracker : AllocationStatsTracker;
    45      const resourceProp = type === 'node' ? 'node' : 'allocation';
    46  
    47      const cachedTracker = registry.get(key);
    48      if (cachedTracker) {
    49        // It's possible for the resource on a cachedTracker to have been
    50        // deleted. Rebind it if that's the case.
    51        if (!exists(cachedTracker, resourceProp))
    52          cachedTracker.set(resourceProp, resource);
    53        return cachedTracker;
    54      }
    55  
    56      const tracker = Constructor.create({
    57        fetch: (url) => this.token.authorizedRequest(url),
    58        [resourceProp]: resource,
    59      });
    60  
    61      registry.set(key, tracker);
    62  
    63      return tracker;
    64    }
    65  }