Merge pull request #5496 from hashicorp/b-ui/reattach-resources-to-stats-trackers

UI: Reattach resources to stats trackers in the event they were destroyed
This commit is contained in:
Michael Lange 2019-04-01 11:31:28 -07:00 committed by GitHub
commit 6d016ed5f0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 4 deletions

View file

@ -11,6 +11,9 @@ import AllocationStatsTracker from 'nomad-ui/utils/classes/allocation-stats-trac
const MAX_STAT_TRACKERS = 10;
let registry;
const exists = (tracker, prop) =>
tracker.get(prop) && !tracker.get(prop).isDestroyed && !tracker.get(prop).isDestroying;
export default Service.extend({
token: service(),
@ -30,13 +33,17 @@ export default Service.extend({
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 cachedTracker = registry.get(key);
if (cachedTracker) {
// It's possible for the resource on a cachedTracker to have been
// deleted. Rebind it if that's the case.
if (!exists(cachedTracker, resourceProp)) cachedTracker.set(resourceProp, resource);
return cachedTracker;
}
const tracker = Constructor.create({
fetch: url => this.get('token').authorizedRequest(url),
[resourceProp]: resource,

View file

@ -1,6 +1,7 @@
import EmberObject from '@ember/object';
import { getOwner } from '@ember/application';
import Service from '@ember/service';
import { run } from '@ember/runloop';
import wait from 'ember-test-helpers/wait';
import { moduleFor, test } from 'ember-qunit';
import Pretender from 'pretender';
@ -104,6 +105,52 @@ test('Has a max size', function(assert) {
assert.ok(ref.limit < Infinity, `A limit (${ref.limit}) is set`);
});
test('Registry re-attaches deleted resources to cached trackers', function(assert) {
const registry = this.subject();
const id = 'some-id';
const node1 = mockNode.create({ id });
let tracker = registry.getTracker(node1);
assert.ok(tracker.get('node'), 'The tracker has a node');
tracker.set('node', null);
assert.notOk(tracker.get('node'), 'The tracker does not have a node');
tracker = registry.getTracker(node1);
assert.equal(
tracker.get('node'),
node1,
'The node was re-attached to the tracker after calling getTracker again'
);
});
test('Registry re-attaches destroyed resources to cached trackers', function(assert) {
const registry = this.subject();
const id = 'some-id';
const node1 = mockNode.create({ id });
let tracker = registry.getTracker(node1);
assert.ok(tracker.get('node'), 'The tracker has a node');
run(() => {
node1.destroy();
});
return wait().then(() => {
assert.ok(tracker.get('node').isDestroyed, 'The tracker node is destroyed');
const node2 = mockNode.create({ id });
tracker = registry.getTracker(node2);
assert.equal(
tracker.get('node'),
node2,
'Since node1 was destroyed but it matches the tracker of node2, node2 is attached to the tracker'
);
});
});
test('Removes least recently used when something needs to be removed', function(assert) {
const registry = this.subject();
const activeNode = mockNode.create({ id: 'active' });