Skip to content

Commit 73ca228

Browse files
Merge pull request #3953 from hashicorp/f-ui-polling-disconnect
UI: Polling Step 3 - Close connections when tabbing away
2 parents 4b3b49b + 27ec2c2 commit 73ca228

17 files changed

+106
-26
lines changed

ui/app/components/client-node-row.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { inject as service } from '@ember/service';
22
import Component from '@ember/component';
33
import { lazyClick } from '../helpers/lazy-click';
44
import { watchRelationship } from 'nomad-ui/utils/properties/watch';
5+
import WithVisibilityDetection from 'nomad-ui/mixins/with-component-visibility-detection';
56

6-
export default Component.extend({
7+
export default Component.extend(WithVisibilityDetection, {
78
store: service(),
89

910
tagName: 'tr',
@@ -27,6 +28,17 @@ export default Component.extend({
2728
}
2829
},
2930

31+
visibilityHandler() {
32+
if (document.hidden) {
33+
this.get('watch').cancelAll();
34+
} else {
35+
const node = this.get('node');
36+
if (node) {
37+
this.get('watch').perform(node, 100);
38+
}
39+
}
40+
},
41+
3042
willDestroy() {
3143
this.get('watch').cancelAll();
3244
this._super(...arguments);

ui/app/components/job-row.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { inject as service } from '@ember/service';
22
import Component from '@ember/component';
33
import { lazyClick } from '../helpers/lazy-click';
44
import { watchRelationship } from 'nomad-ui/utils/properties/watch';
5+
import WithVisibilityDetection from 'nomad-ui/mixins/with-component-visibility-detection';
56

6-
export default Component.extend({
7+
export default Component.extend(WithVisibilityDetection, {
78
store: service(),
89

910
tagName: 'tr',
@@ -27,6 +28,17 @@ export default Component.extend({
2728
}
2829
},
2930

31+
visibilityHandler() {
32+
if (document.hidden) {
33+
this.get('watch').cancelAll();
34+
} else {
35+
const job = this.get('job');
36+
if (job && !job.get('isLoading')) {
37+
this.get('watch').perform(job, 100);
38+
}
39+
}
40+
},
41+
3042
willDestroy() {
3143
this.get('watch').cancelAll();
3244
this._super(...arguments);

ui/app/controllers/jobs/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export default Controller.extend(Sortable, Searchable, {
3737
'system.namespaces.length',
3838
function() {
3939
const hasNamespaces = this.get('system.namespaces.length');
40-
const activeNamespace = this.get('system.activeNamespace.id');
40+
const activeNamespace = this.get('system.activeNamespace.id') || 'default';
4141

4242
return this.get('model')
4343
.filter(job => !hasNamespaces || job.get('namespace.id') === activeNamespace)

ui/app/mixins/window-resizable.js

+5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
import Mixin from '@ember/object/mixin';
22
import { run } from '@ember/runloop';
3+
import { assert } from '@ember/debug';
34
import $ from 'jquery';
45

56
export default Mixin.create({
7+
windowResizeHandler() {
8+
assert('windowResizeHandler needs to be overridden in the Component', false);
9+
},
10+
611
setupWindowResize: function() {
712
run.scheduleOnce('afterRender', this, () => {
813
this.set('_windowResizeHandler', this.get('windowResizeHandler').bind(this));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Mixin from '@ember/object/mixin';
2+
import { assert } from '@ember/debug';
3+
4+
export default Mixin.create({
5+
visibilityHandler() {
6+
assert('visibilityHandler needs to be overridden in the Component', false);
7+
},
8+
9+
setupDocumentVisibility: function() {
10+
this.set('_visibilityHandler', this.get('visibilityHandler').bind(this));
11+
document.addEventListener('visibilitychange', this.get('_visibilityHandler'));
12+
}.on('init'),
13+
14+
removeDocumentVisibility: function() {
15+
document.removeEventListener('visibilitychange', this.get('_visibilityHandler'));
16+
}.on('willDestroy'),
17+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Mixin from '@ember/object/mixin';
2+
import { assert } from '@ember/debug';
3+
4+
export default Mixin.create({
5+
visibilityHandler() {
6+
assert('visibilityHandler needs to be overridden in the Route', false);
7+
},
8+
9+
setupDocumentVisibility: function() {
10+
this.set('_visibilityHandler', this.get('visibilityHandler').bind(this));
11+
document.addEventListener('visibilitychange', this.get('_visibilityHandler'));
12+
}.on('activate'),
13+
14+
removeDocumentVisibility: function() {
15+
document.removeEventListener('visibilitychange', this.get('_visibilityHandler'));
16+
}.on('deactivate'),
17+
});

ui/app/mixins/with-watchers.js

+27-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,38 @@
11
import Mixin from '@ember/object/mixin';
22
import { computed } from '@ember/object';
33
import { assert } from '@ember/debug';
4+
import WithVisibilityDetection from './with-route-visibility-detection';
45

5-
export default Mixin.create({
6+
export default Mixin.create(WithVisibilityDetection, {
67
watchers: computed(() => []),
78

9+
cancelAllWatchers() {
10+
this.get('watchers').forEach(watcher => {
11+
assert('Watchers must be Ember Concurrency Tasks.', !!watcher.cancelAll);
12+
watcher.cancelAll();
13+
});
14+
},
15+
16+
startWatchers() {
17+
assert('startWatchers needs to be overridden in the Route', false);
18+
},
19+
20+
setupController() {
21+
this.startWatchers(...arguments);
22+
return this._super(...arguments);
23+
},
24+
25+
visibilityHandler() {
26+
if (document.hidden) {
27+
this.cancelAllWatchers();
28+
} else {
29+
this.startWatchers(this.controller, this.controller.get('model'));
30+
}
31+
},
32+
833
actions: {
934
willTransition() {
10-
this.get('watchers').forEach(watcher => {
11-
assert('Watchers must be Ember Concurrency Tasks.', !!watcher.cancelAll);
12-
watcher.cancelAll();
13-
});
35+
this.cancelAllWatchers();
1436
},
1537
},
1638
});

ui/app/routes/allocations/allocation.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ import { watchRecord } from 'nomad-ui/utils/properties/watch';
55
import WithWatchers from 'nomad-ui/mixins/with-watchers';
66

77
export default Route.extend(WithModelErrorHandling, WithWatchers, {
8-
setupController(controller, model) {
8+
startWatchers(controller, model) {
99
controller.set('watcher', this.get('watch').perform(model));
10-
return this._super(...arguments);
1110
},
1211

1312
watch: watchRecord('allocation'),

ui/app/routes/application.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { inject as service } from '@ember/service';
22
import Route from '@ember/routing/route';
3+
import { AbortError } from 'ember-data/adapters/errors';
34

45
export default Route.extend({
56
config: service(),
@@ -22,7 +23,9 @@ export default Route.extend({
2223
},
2324

2425
error(error) {
25-
this.controllerFor('application').set('error', error);
26+
if (!(error instanceof AbortError)) {
27+
this.controllerFor('application').set('error', error);
28+
}
2629
},
2730
},
2831
});

ui/app/routes/clients/client.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@ export default Route.extend(WithWatchers, {
1919
return model && model.get('allocations');
2020
},
2121

22-
setupController(controller, model) {
22+
startWatchers(controller, model) {
2323
controller.set('watchModel', this.get('watch').perform(model));
2424
controller.set('watchAllocations', this.get('watchAllocations').perform(model));
25-
return this._super(...arguments);
2625
},
2726

2827
watch: watchRecord('node'),

ui/app/routes/clients/index.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ import { watchAll } from 'nomad-ui/utils/properties/watch';
44
import WithWatchers from 'nomad-ui/mixins/with-watchers';
55

66
export default Route.extend(WithWatchers, {
7-
setupController(controller) {
7+
startWatchers(controller) {
88
controller.set('watcher', this.get('watch').perform());
9-
return this._super(...arguments);
109
},
1110

1211
watch: watchAll('node'),

ui/app/routes/jobs/index.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ import { watchAll } from 'nomad-ui/utils/properties/watch';
44
import WithWatchers from 'nomad-ui/mixins/with-watchers';
55

66
export default Route.extend(WithWatchers, {
7-
setupController(controller) {
7+
startWatchers(controller) {
88
controller.set('modelWatch', this.get('watch').perform());
9-
return this._super(...arguments);
109
},
1110

1211
watch: watchAll('job'),

ui/app/routes/jobs/job/deployments.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ export default Route.extend(WithWatchers, {
1010
return RSVP.all([job.get('deployments'), job.get('versions')]).then(() => job);
1111
},
1212

13-
setupController(controller, model) {
13+
startWatchers(controller, model) {
1414
controller.set('watchDeployments', this.get('watchDeployments').perform(model));
1515
controller.set('watchVersions', this.get('watchVersions').perform(model));
16-
return this._super(...arguments);
1716
},
1817

1918
watchDeployments: watchRelationship('deployments'),

ui/app/routes/jobs/job/index.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@ import { watchRecord, watchRelationship } from 'nomad-ui/utils/properties/watch'
44
import WithWatchers from 'nomad-ui/mixins/with-watchers';
55

66
export default Route.extend(WithWatchers, {
7-
setupController(controller, model) {
7+
startWatchers(controller, model) {
88
controller.set('watchers', {
99
model: this.get('watch').perform(model),
1010
summary: this.get('watchSummary').perform(model),
1111
evaluations: this.get('watchEvaluations').perform(model),
1212
deployments: this.get('watchDeployments').perform(model),
1313
});
14-
15-
return this._super(...arguments);
1614
},
1715

1816
watch: watchRecord('job'),

ui/app/routes/jobs/job/task-group.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,13 @@ export default Route.extend(WithWatchers, {
1919
});
2020
},
2121

22-
setupController(controller, model) {
22+
startWatchers(controller, model) {
2323
const job = model.get('job');
2424
controller.set('watchers', {
2525
job: this.get('watchJob').perform(job),
2626
summary: this.get('watchSummary').perform(job),
2727
allocations: this.get('watchAllocations').perform(job),
2828
});
29-
return this._super(...arguments);
3029
},
3130

3231
watchJob: watchRecord('job'),

ui/app/routes/jobs/job/versions.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ export default Route.extend(WithWatchers, {
99
return job.get('versions').then(() => job);
1010
},
1111

12-
setupController(controller, model) {
12+
startWatchers(controller, model) {
1313
controller.set('watcher', this.get('watchVersions').perform(model));
14-
return this._super(...arguments);
1514
},
1615

1716
watchVersions: watchRelationship('versions'),

ui/mirage/factories/job.js

+1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ export default Factory.extend({
113113
const jobSummary = server.create('job-summary', hasChildren ? 'withChildren' : 'withSummary', {
114114
groupNames: groups.mapBy('name'),
115115
job,
116+
job_id: job.id,
116117
namespace: job.namespace,
117118
});
118119

0 commit comments

Comments
 (0)