Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions ui/app/components/primary-metric/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ export default class NodePrimaryMetric extends Component {

@task(function* () {
do {
this.tracker.poll.perform();
const tracker = this.tracker;
const nodeId = tracker && get(tracker, 'node.id');
if (tracker && nodeId) {
tracker.poll.perform();
}
yield timeout(100);
} while (!Ember.testing);
})
Expand All @@ -88,6 +92,8 @@ export default class NodePrimaryMetric extends Component {
willDestroy() {
super.willDestroy(...arguments);
this.poller.cancelAll();
this.tracker.signalPause.perform();
if (this.tracker) {
this.tracker.signalPause.perform();
}
}
}
43 changes: 37 additions & 6 deletions ui/app/services/stats-trackers-registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,49 @@ export default class StatsTrackersRegistryService extends Service {
if (!resource) return;

const type = resource && resource.constructor.modelName;
const key = `${type}:${resource.get('id')}`;
const resourceId = resource.get('id');

if (!resourceId) {
return;
}

const key = `${type}:${resourceId}`;
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 cachedResource = cachedTracker.get(resourceProp);
const shouldReuse =
exists(cachedTracker, resourceProp) && cachedResource === resource;

if (shouldReuse) {
return cachedTracker;
}

// Replace stale/mismatched trackers instead of mutating an already-used
// tracker during render.
if (
cachedTracker.poll &&
typeof cachedTracker.poll.cancelAll === 'function'
) {
cachedTracker.poll.cancelAll();
}
if (
cachedTracker.signalPause &&
typeof cachedTracker.signalPause.cancelAll === 'function'
) {
cachedTracker.signalPause.cancelAll();
}

const replacementTracker = Constructor.create({
fetch: (url) => this.token.authorizedRequest(url),
[resourceProp]: resource,
});

registry.set(key, replacementTracker);
return replacementTracker;
}

const tracker = Constructor.create({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export function setupPrimaryMetricMocks(hooks, tasks = []) {
const trackerSignalPauseSpy = (this.trackerSignalPauseSpy = sinon.spy());

const MockTracker = EmberObject.extend({
node: computed(function () {
return { id: 'test-node-id' };
}),
poll: task(function* () {
yield trackerPollSpy();
}),
Expand Down
16 changes: 12 additions & 4 deletions ui/tests/unit/services/stats-trackers-registry-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ module('Unit | Service | Stats Trackers Registry', function (hooks) {
);
});

test('Registry does not depend on persistent object references', function (assert) {
test('Registry replaces cached tracker when resource reference changes for same id', function (assert) {
const registry = this.subject();
const id = 'some-id';

Expand All @@ -122,10 +122,18 @@ module('Unit | Service | Stats Trackers Registry', function (hooks) {
'And the same className'
);

const tracker1 = registry.getTracker(node1);
const tracker2 = registry.getTracker(node2);

assert.notEqual(
tracker1,
tracker2,
'Returns a replacement tracker for a different resource reference with same id'
);
assert.equal(
registry.getTracker(node1),
registry.getTracker(node2),
'Return the same tracker'
tracker2.get('node'),
node2,
'The replacement tracker is bound to the latest resource reference'
);
assert.equal(
registry.get('registryRef').size,
Expand Down
Loading