Merge lp:~hatch/juju-gui/parse-pending-types into lp:juju-gui/experimental

Proposed by Jeff Pihach
Status: Merged
Merged at revision: 1217
Proposed branch: lp:~hatch/juju-gui/parse-pending-types
Merge into: lp:juju-gui/experimental
Diff against target: 282 lines (+52/-71)
9 files modified
app/models/handlers.js (+4/-1)
app/models/models.js (+16/-17)
app/store/env/simulator.js (+2/-12)
app/views/environment.js (+2/-23)
app/views/inspector.js (+1/-1)
app/views/utils.js (+15/-7)
app/views/viewlets/service-overview.js (+6/-4)
test/test_model.js (+5/-5)
test/test_service_module.js (+1/-1)
To merge this branch: bzr merge lp:~hatch/juju-gui/parse-pending-types
Reviewer Review Type Date Requested Status
Juju GUI Hackers Pending
Review via email: mp+197441@code.launchpad.net

Description of the change

Adds pending and dying statuses to the inspector

A service in various states of pending are now properly represented in the
inspector.

Dying services are now left on the canvas with their inspectors until the service
is entirely destroyed from Juju.

https://codereview.appspot.com/36240043/

To post a comment you must log in.
Revision history for this message
Jeff Pihach (hatch) wrote :

Reviewers: mp+197441_code.launchpad.net,

Message:
Please take a look.

Description:
Adds pending and dying statuses to the inspector

A service in various states of pending are now properly represented in
the
inspector.

Dying services are now left on the canvas with their inspectors until
the service
is entirely destroyed from Juju.

To QA:
Sandbox:
Deploy some services and make sure you can destroy them in various ways.
Deploy a service with a lot of units and wait for the simulator to show
   pending and installing statuses

Real Env:
Deploy 4 instances of failtester
Set one to fail on install hook
Open one of the pending services inspectors and then delete it from the
console
It should enter a 'dying' state then remove from the canvas when
finished
Wait for the remaining failtester services to come green/red
Destroy one from the GUI, it should enter a 'dying' state and then
remove from the canvas
   closing the inspector when it's done.
Open the other green one, destroy it from the console, it should enter a
'dying' state and
   then remove from the canvas
Open the red one's inspector, destroy it from the console, nothing
should happen in the GUI
Resolve the unit in error in the GUI and the service should enter a
'dying' state then
   remove from the canvas when done.

https://code.launchpad.net/~hatch/juju-gui/parse-pending-types/+merge/197441

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/36240043/

Affected files (+54, -71 lines):
   A [revision details]
   M app/models/handlers.js
   M app/models/models.js
   M app/store/env/simulator.js
   M app/views/environment.js
   M app/views/inspector.js
   M app/views/utils.js
   M app/views/viewlets/service-overview.js
   M test/test_model.js
   M test/test_service_module.js

Revision history for this message
Madison Scott-Clary (makyo) wrote :

LGTM, QA okay, one question, feel free to say no! Thanks.

https://codereview.appspot.com/36240043/diff/1/app/models/models.js
File app/models/models.js (right):

https://codereview.appspot.com/36240043/diff/1/app/models/models.js#newcode205
app/models/models.js:205: if (life === ALIVE || life === 'dying') {
We have a constant ALIVE, might it make sense to do he samefor DYING?

https://codereview.appspot.com/36240043/

Revision history for this message
Jeff Pihach (hatch) wrote :

*** Submitted:

Adds pending and dying statuses to the inspector

A service in various states of pending are now properly represented in
the
inspector.

Dying services are now left on the canvas with their inspectors until
the service
is entirely destroyed from Juju.

R=matthew.scott
CC=
https://codereview.appspot.com/36240043

https://codereview.appspot.com/36240043/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'app/models/handlers.js'
2--- app/models/handlers.js 2013-11-19 22:30:18 +0000
3+++ app/models/handlers.js 2013-12-02 21:33:17 +0000
4@@ -172,7 +172,10 @@
5 public_address: change.PublicAddress
6 };
7 var service = db.services.getById(change.Name.split('/')[0]);
8- service.get('units').process_delta(action, unitData, db);
9+ if (service) {
10+ // The service can be destroyed before the last unit delta comes in.
11+ service.get('units').process_delta(action, unitData, db);
12+ }
13 db.machines.process_delta(action, machineData, db);
14 },
15
16
17=== modified file 'app/models/models.js'
18--- app/models/models.js 2013-11-26 20:38:05 +0000
19+++ app/models/models.js 2013-12-02 21:33:17 +0000
20@@ -191,18 +191,21 @@
21 },
22
23 /**
24- Return true if this service life is "alive", false otherwise.
25+ Return true if this service life is 'alive' or 'dying', false otherwise.
26
27 A model instance is alive if its life cycle (i.e. the "life" attribute)
28- is set to "alive". Other possible values, as they arrive from the
29- juju-core delta stream, are "dying" and "dead", in which cases the
30- service is not considered alive.
31+ is set to 'alive' or 'dying'. The other possible value, as they arrive
32+ from the juju-core delta stream is 'dead'.
33
34 @method isAlive
35 @return {Boolean} Whether this service is alive.
36 */
37 isAlive: function() {
38- return this.get('life') === ALIVE;
39+ var life = this.get('life');
40+ if (life === ALIVE || life === 'dying') {
41+ return true;
42+ }
43+ return false;
44 },
45
46 /**
47@@ -413,14 +416,10 @@
48 model: Service,
49
50 /**
51- Return a list of visible model instances.
52-
53- A model instance is visible when it is alive or when, even if it is dying
54- or dead, one or more of its units are in an error state.
55- In the latter case, we want to still display the service in order to
56- allow users to retry or resolve its units.
57-
58- @method alive
59+ Return a list of visible model instances. A model instance is visible
60+ when it is alive or dying.
61+
62+ @method visible
63 @return {Y.ModelList} The resulting visible model instances.
64 */
65 visible: function() {
66@@ -593,10 +592,12 @@
67 get_informative_states_for_service: function(service) {
68 var aggregate_map = {},
69 relationError = {},
70- units_for_service = service.get('units');
71+ units_for_service = service.get('units'),
72+ serviceLife = service.get('life');
73
74 units_for_service.each(function(unit) {
75- var state = utils.determineCategoryType(utils.simplifyState(unit));
76+ var state = utils.determineCategoryType(
77+ utils.simplifyState(unit, serviceLife));
78 if (aggregate_map[state] === undefined) {
79 aggregate_map[state] = 1;
80 } else {
81@@ -633,9 +634,7 @@
82 var previous_unit_count = service.get('unit_count');
83 service.set('unit_count', sum);
84 service.set('aggregated_status', aggregate[0]);
85-
86 service.set('relationChangeTrigger', { error: aggregate[1] });
87-
88 // Set Google Analytics tracking event.
89 if (previous_unit_count !== sum && window._gaq) {
90 window._gaq.push(['_trackEvent', 'Service Stats', 'Update',
91
92=== modified file 'app/store/env/simulator.js'
93--- app/store/env/simulator.js 2013-11-22 22:52:30 +0000
94+++ app/store/env/simulator.js 2013-12-02 21:33:17 +0000
95@@ -157,18 +157,8 @@
96 unit.agent_state_info = undefined;
97 unit.agent_state_data = {};
98 } else if (roll <= 0.7) {
99- if (window.flags && window.flags.simPend) {
100- // Because the GUI does not yet support parsing the 'life'
101- // status attribute from core and including it in the
102- // aggregate status this is here to simply simulate the
103- // functionality in the inspector unit list, until it is.
104- if (roll <= 0.4) {
105- unit.agent_state = 'dying';
106- } else if (roll <= 0.5) {
107- unit.agent_state = 'installing';
108- } else {
109- unit.agent_state = 'pending';
110- }
111+ if (roll <= 0.5) {
112+ unit.agent_state = 'installing';
113 } else {
114 unit.agent_state = 'pending';
115 }
116
117=== modified file 'app/views/environment.js'
118--- app/views/environment.js 2013-11-13 15:41:46 +0000
119+++ app/views/environment.js 2013-12-02 21:33:17 +0000
120@@ -151,32 +151,11 @@
121 this.topo.fire('hideServiceMenu');
122 }, this);
123
124- model.get('units').on('deltaChange', function(e) {
125- var service = e.service;
126- var units = service.get('units');
127-
128- var started = !units.some(function(unit) {
129- if ((/-?error$/).test(unit.agent_state)) {
130- return true;
131- }
132- });
133-
134- if (started && service.get('life') === 'dying') {
135- var inspector = this.getInspector(service.get('packageName'));
136- if (inspector) { inspector.viewletManager.destroy(); }
137- this.topo.fire('hideServiceMenu');
138- }
139- }, this);
140-
141 // If the service is destroyed from the console then we need to
142 // destroy the inspector and hide the service menu.
143- model.after(['lifeChange', 'destroy'], function(e) {
144+ model.on('destroy', function(e) {
145 var service = e.currentTarget;
146- // The user can put the service in a dying state from the console
147- // but it will not be destroyed if any of its units has errors.
148- if (service.isAlive() || service.hasErrors()) { return; }
149-
150- var inspector = this.getInspector(service.get('packageName'));
151+ var inspector = this.getInspector(service.get('id'));
152 if (inspector) { inspector.viewletManager.destroy(); }
153 this.topo.fire('hideServiceMenu');
154 }, this);
155
156=== modified file 'app/views/inspector.js'
157--- app/views/inspector.js 2013-10-11 19:33:07 +0000
158+++ app/views/inspector.js 2013-12-02 21:33:17 +0000
159@@ -507,8 +507,8 @@
160 */
161 _onInitiateDestroy: function(evt) {
162 evt.halt();
163- this.closeInspector();
164 this.initiateServiceDestroy();
165+ this._onCancelDestroy(evt);
166 this.options.environment.topo.fire('clearState');
167 },
168
169
170=== modified file 'app/views/utils.js'
171--- app/views/utils.js 2013-11-27 19:27:32 +0000
172+++ app/views/utils.js 2013-12-02 21:33:17 +0000
173@@ -1232,14 +1232,21 @@
174
175 @method simplifyState
176 @param {Object} unit A service unit.
177+ @param {String} life The life status of the units service.
178 @return {String} the filtered agent state of the unit.
179 */
180- utils.simplifyState = function(unit) {
181- var state = unit.agent_state;
182- if (state === 'started') { return 'running'; }
183- if ((/-?error$/).test(state)) { return 'error'; }
184- // "pending", "installed", and "stopped", plus anything unforeseen
185- return state;
186+ utils.simplifyState = function(unit, life) {
187+ var state = unit.agent_state,
188+ inError = (/-?error$/).test(state);
189+ if (life === 'dying' && !inError) {
190+ return 'dying';
191+ } else {
192+ if (state === 'started') { return 'running'; }
193+ if (inError) { return 'error'; }
194+ // "pending", "installed", and "stopped", plus anything unforeseen
195+ return state;
196+ }
197+
198 };
199
200 /**
201@@ -1267,7 +1274,8 @@
202
203 @method determineCategoryType
204 @param {String} category The category name to test.
205- @param {String} The category type 'error', 'landscape', 'pending', 'running'
206+ @return {String} The category type
207+ 'error', 'landscape', 'pending', 'running'
208 */
209 utils.determineCategoryType = function(category) {
210 if ((/fail|error/).test(category)) { return 'error'; }
211
212=== modified file 'app/views/viewlets/service-overview.js'
213--- app/views/viewlets/service-overview.js 2013-11-21 23:21:49 +0000
214+++ app/views/viewlets/service-overview.js 2013-12-02 21:33:17 +0000
215@@ -83,11 +83,14 @@
216 [{ type: 'service', upgradeAvailable: true, upgradeTo: ...}].
217 */
218 function updateStatusList(unitList) {
219+ // Disable: Possible strict violation for the entire function
220+ /* jshint -W040 */
221 var statuses = [],
222- unitByStatus = {};
223+ unitByStatus = {},
224+ serviceLife = this.model.get('life');
225
226 unitList.each(function(unit) {
227- var category = utils.simplifyState(unit);
228+ var category = utils.simplifyState(unit, serviceLife);
229 // If the unit is in error we want it's category to be it's real error.
230 if (category === 'error') { category = unit.agent_state_info; }
231
232@@ -112,8 +115,7 @@
233 units: unitByStatus[category]
234 });
235 });
236- // Disable: Possible strict violation
237- /* jshint -W040 */
238+
239 return sortStatuses(addCharmUpgrade(statuses, this.model));
240 }
241
242
243=== modified file 'test/test_model.js'
244--- test/test_model.js 2013-11-26 22:30:42 +0000
245+++ test/test_model.js 2013-12-02 21:33:17 +0000
246@@ -1034,9 +1034,9 @@
247 assert.isTrue(django.isAlive());
248 });
249
250- it('instances identify if they are not alive (dying or dead)', function() {
251- assert.isFalse(rails.isAlive(), rails.get('id'));
252- assert.isFalse(wordpress.isAlive(), wordpress.get('id'));
253+ it('instances identify if they are not alive (dead)', function() {
254+ assert.isTrue(rails.isAlive(), rails.get('id'));
255+ assert.isTrue(wordpress.isAlive(), wordpress.get('id'));
256 assert.isFalse(mysql.isAlive(), mysql.get('id'));
257 });
258
259@@ -1052,8 +1052,8 @@
260
261 it('can be filtered so that it returns only visible models', function() {
262 var filtered = list.visible();
263- assert.strictEqual(2, filtered.size());
264- assert.deepEqual([django, wordpress], filtered.toArray());
265+ assert.strictEqual(filtered.size(), 3);
266+ assert.deepEqual(filtered.toArray(), [rails, django, wordpress]);
267 });
268 });
269 });
270
271=== modified file 'test/test_service_module.js'
272--- test/test_service_module.js 2013-11-21 12:18:26 +0000
273+++ test/test_service_module.js 2013-12-02 21:33:17 +0000
274@@ -258,7 +258,7 @@
275 // There are five services in total.
276 assert.strictEqual(5, db.services.size(), 'total');
277 // But only three of those are actually displayed.
278- assert.strictEqual(3, Y.Object.size(boxes), 'displayed');
279+ assert.strictEqual(4, Y.Object.size(boxes), 'displayed');
280 // And they are the visible ones.
281 assert.deepPropertyVal(boxes, 'haproxy.model', haproxy);
282 assert.deepPropertyVal(boxes, 'django.model', django);

Subscribers

People subscribed via source and target branches