Show More
@@ -141,18 +141,24 b' define([' | |||||
141 | knw.set_message("Restarting kernel", 2000); |
|
141 | knw.set_message("Restarting kernel", 2000); | |
142 | }); |
|
142 | }); | |
143 |
|
143 | |||
144 | this.events.on('status_autorestarting.Kernel', function () { |
|
144 | this.events.on('status_autorestarting.Kernel', function (evt, info) { | |
145 | dialog.modal({ |
|
145 | // only show the dialog on the first restart attempt | |
146 | notebook: that.notebook, |
|
146 | if (info.attempt == 1) { | |
147 | keyboard_manager: that.keyboard_manager, |
|
147 | // hide existing modal dialog | |
148 | title: "Kernel Restarting", |
|
148 | $(".modal").modal('hide'); | |
149 | body: "The kernel appears to have died. It will restart automatically.", |
|
149 | ||
150 |
|
|
150 | dialog.modal({ | |
151 |
|
|
151 | notebook: that.notebook, | |
152 | class : "btn-primary" |
|
152 | keyboard_manager: that.keyboard_manager, | |
|
153 | title: "Kernel Restarting", | |||
|
154 | body: "The kernel appears to have died. It will restart automatically.", | |||
|
155 | buttons: { | |||
|
156 | OK : { | |||
|
157 | class : "btn-primary" | |||
|
158 | } | |||
153 | } |
|
159 | } | |
154 | } |
|
160 | }); | |
155 |
} |
|
161 | }; | |
156 |
|
162 | |||
157 | that.save_widget.update_document_title(); |
|
163 | that.save_widget.update_document_title(); | |
158 | knw.danger("Dead kernel"); |
|
164 | knw.danger("Dead kernel"); | |
@@ -174,9 +180,13 b' define([' | |||||
174 | }); |
|
180 | }); | |
175 |
|
181 | |||
176 | this.events.on('connection_failed.Kernel', function () { |
|
182 | this.events.on('connection_failed.Kernel', function () { | |
|
183 | // hide existing dialog | |||
|
184 | $(".modal").modal('hide'); | |||
|
185 | ||||
177 | var msg = "A WebSocket connection could not be established." + |
|
186 | var msg = "A WebSocket connection could not be established." + | |
178 | " You will NOT be able to run code. Check your" + |
|
187 | " You will NOT be able to run code. Check your" + | |
179 | " network connection or notebook server configuration."; |
|
188 | " network connection or notebook server configuration."; | |
|
189 | ||||
180 | dialog.modal({ |
|
190 | dialog.modal({ | |
181 | title: "WebSocket connection failed", |
|
191 | title: "WebSocket connection failed", | |
182 | body: msg, |
|
192 | body: msg, | |
@@ -193,34 +203,48 b' define([' | |||||
193 | }); |
|
203 | }); | |
194 | }); |
|
204 | }); | |
195 |
|
205 | |||
196 |
this.events.on(' |
|
206 | this.events.on('status_killed.Kernel status_killed.Session', function () { | |
197 | that.save_widget.update_document_title(); |
|
207 | that.save_widget.update_document_title(); | |
198 | knw.danger("Dead kernel"); |
|
208 | knw.danger("Dead kernel"); | |
199 | $kernel_ind_icon.attr('class','kernel_dead_icon').attr('title','Kernel Dead'); |
|
209 | $kernel_ind_icon.attr('class','kernel_dead_icon').attr('title','Kernel Dead'); | |
200 | }); |
|
210 | }); | |
201 |
|
211 | |||
202 | this.events.on('kernel_dead.Kernel', function () { |
|
212 | this.events.on('kernel_dead.Kernel', function () { | |
203 | var msg = 'The kernel has died, and the automatic restart has failed.' + |
|
|||
204 | ' It is possible the kernel cannot be restarted.' + |
|
|||
205 | ' If you are not able to restart the kernel, you will still be able to save' + |
|
|||
206 | ' the notebook, but running code will no longer work until the notebook' + |
|
|||
207 | ' is reopened.'; |
|
|||
208 |
|
213 | |||
209 | dialog.modal({ |
|
214 | var showMsg = function () { | |
210 | title: "Dead kernel", |
|
215 | // hide existing dialog | |
211 | body : msg, |
|
216 | $(".modal").modal('hide'); | |
212 | keyboard_manager: that.keyboard_manager, |
|
217 | ||
213 | notebook: that.notebook, |
|
218 | var msg = 'The kernel has died, and the automatic restart has failed.' + | |
214 | buttons : { |
|
219 | ' It is possible the kernel cannot be restarted.' + | |
215 | "Manual Restart": { |
|
220 | ' If you are not able to restart the kernel, you will still be able to save' + | |
216 | class: "btn-danger", |
|
221 | ' the notebook, but running code will no longer work until the notebook' + | |
217 |
|
|
222 | ' is reopened.'; | |
218 | that.notebook.start_session(); |
|
223 | ||
219 | } |
|
224 | dialog.modal({ | |
220 |
|
|
225 | title: "Dead kernel", | |
|
226 | body : msg, | |||
|
227 | keyboard_manager: that.keyboard_manager, | |||
|
228 | notebook: that.notebook, | |||
|
229 | buttons : { | |||
|
230 | "Manual Restart": { | |||
|
231 | class: "btn-danger", | |||
|
232 | click: function () { | |||
|
233 | that.notebook.start_session(); | |||
|
234 | } | |||
|
235 | }, | |||
221 | "Don't restart": {} |
|
236 | "Don't restart": {} | |
222 | } |
|
237 | } | |
223 | }); |
|
238 | }); | |
|
239 | ||||
|
240 | return false; | |||
|
241 | }; | |||
|
242 | ||||
|
243 | that.save_widget.update_document_title(); | |||
|
244 | knw.danger("Dead kernel", undefined, showMsg); | |||
|
245 | $kernel_ind_icon.attr('class','kernel_dead_icon').attr('title','Kernel Dead'); | |||
|
246 | ||||
|
247 | showMsg(); | |||
224 | }); |
|
248 | }); | |
225 |
|
249 | |||
226 | this.events.on('kernel_dead.Session', function (evt, info) { |
|
250 | this.events.on('kernel_dead.Session', function (evt, info) { | |
@@ -246,6 +270,9 b' define([' | |||||
246 | cm_open = $.proxy(cm.refresh, cm); |
|
270 | cm_open = $.proxy(cm.refresh, cm); | |
247 | } |
|
271 | } | |
248 |
|
272 | |||
|
273 | // hide existing modal dialog | |||
|
274 | $(".modal").modal('hide'); | |||
|
275 | ||||
249 | dialog.modal({ |
|
276 | dialog.modal({ | |
250 | title: "Failed to start the kernel", |
|
277 | title: "Failed to start the kernel", | |
251 | body : msg, |
|
278 | body : msg, |
@@ -61,6 +61,8 b' define([' | |||||
61 |
|
61 | |||
62 | this.last_msg_id = null; |
|
62 | this.last_msg_id = null; | |
63 | this.last_msg_callbacks = {}; |
|
63 | this.last_msg_callbacks = {}; | |
|
64 | ||||
|
65 | this._autorestart_attempt = 0; | |||
64 | }; |
|
66 | }; | |
65 |
|
67 | |||
66 | /** |
|
68 | /** | |
@@ -110,6 +112,10 b' define([' | |||||
110 | this.events.on('status_ready.Kernel', record_status); |
|
112 | this.events.on('status_ready.Kernel', record_status); | |
111 | this.events.on('status_killed.Kernel', record_status); |
|
113 | this.events.on('status_killed.Kernel', record_status); | |
112 | this.events.on('kernel_dead.Kernel', record_status); |
|
114 | this.events.on('kernel_dead.Kernel', record_status); | |
|
115 | ||||
|
116 | this.events.on('status_ready.Kernel', function () { | |||
|
117 | that._autorestart_attempt = 0; | |||
|
118 | }); | |||
113 | }; |
|
119 | }; | |
114 |
|
120 | |||
115 | /** |
|
121 | /** | |
@@ -922,8 +928,9 b' define([' | |||||
922 | // in that it means the kernel died and the server is restarting it. |
|
928 | // in that it means the kernel died and the server is restarting it. | |
923 | // status_restarting sets the notification widget, |
|
929 | // status_restarting sets the notification widget, | |
924 | // autorestart shows the more prominent dialog. |
|
930 | // autorestart shows the more prominent dialog. | |
|
931 | this._autorestart_attempt = this._autorestart_attempt + 1; | |||
925 | this.events.trigger('status_restarting.Kernel', {kernel: this}); |
|
932 | this.events.trigger('status_restarting.Kernel', {kernel: this}); | |
926 | this.events.trigger('status_autorestarting.Kernel', {kernel: this}); |
|
933 | this.events.trigger('status_autorestarting.Kernel', {kernel: this, attempt: this._autorestart_attempt}); | |
927 |
|
934 | |||
928 | } else if (execution_state === 'dead') { |
|
935 | } else if (execution_state === 'dead') { | |
929 | this.events.trigger('kernel_dead.Kernel', {kernel: this}); |
|
936 | this.events.trigger('kernel_dead.Kernel', {kernel: this}); |
@@ -217,12 +217,6 b' casper.notebook_test(function () {' | |||||
217 | // wait for any last idle/busy messages to be handled |
|
217 | // wait for any last idle/busy messages to be handled | |
218 | this.wait_for_kernel_ready(); |
|
218 | this.wait_for_kernel_ready(); | |
219 |
|
219 | |||
220 | // TODO: test for failed restart, that it triggers |
|
|||
221 | // kernel_dead.Kernel? How to do this? |
|
|||
222 |
|
||||
223 | // TODO: test for status_autorestarting.Kernel? how to trigger |
|
|||
224 | // this? |
|
|||
225 |
|
||||
226 | // check for events in the interrupt cycle |
|
220 | // check for events in the interrupt cycle | |
227 | this.event_test( |
|
221 | this.event_test( | |
228 | 'interrupt', |
|
222 | 'interrupt', | |
@@ -271,4 +265,53 b' casper.notebook_test(function () {' | |||||
271 | }); |
|
265 | }); | |
272 | } |
|
266 | } | |
273 | ); |
|
267 | ); | |
|
268 | ||||
|
269 | // start the kernel back up | |||
|
270 | this.thenEvaluate(function () { | |||
|
271 | IPython.notebook.kernel.restart(); | |||
|
272 | }); | |||
|
273 | this.waitFor(this.kernel_running); | |||
|
274 | this.wait_for_kernel_ready(); | |||
|
275 | ||||
|
276 | // test handling of autorestarting messages | |||
|
277 | this.event_test( | |||
|
278 | 'autorestarting', | |||
|
279 | [ | |||
|
280 | 'status_restarting.Kernel', | |||
|
281 | 'status_autorestarting.Kernel', | |||
|
282 | ], | |||
|
283 | function () { | |||
|
284 | this.thenEvaluate(function () { | |||
|
285 | var cell = IPython.notebook.get_cell(0); | |||
|
286 | cell.set_text('import os\n' + 'os._exit(1)'); | |||
|
287 | cell.execute(); | |||
|
288 | }); | |||
|
289 | } | |||
|
290 | ); | |||
|
291 | this.wait_for_kernel_ready(); | |||
|
292 | ||||
|
293 | // test handling of failed restart | |||
|
294 | this.event_test( | |||
|
295 | 'failed_restart', | |||
|
296 | [ | |||
|
297 | 'status_restarting.Kernel', | |||
|
298 | 'status_autorestarting.Kernel', | |||
|
299 | 'kernel_dead.Kernel' | |||
|
300 | ], | |||
|
301 | function () { | |||
|
302 | this.thenEvaluate(function () { | |||
|
303 | var cell = IPython.notebook.get_cell(0); | |||
|
304 | cell.set_text("import os\n" + | |||
|
305 | "from IPython.kernel.connect import get_connection_file\n" + | |||
|
306 | "with open(get_connection_file(), 'w') as f:\n" + | |||
|
307 | " f.write('garbage')\n" + | |||
|
308 | "os._exit(1)"); | |||
|
309 | cell.execute(); | |||
|
310 | }); | |||
|
311 | }, | |||
|
312 | ||||
|
313 | // need an extra-long timeout, because it needs to try | |||
|
314 | // restarting the kernel 5 times! | |||
|
315 | 20000 | |||
|
316 | ); | |||
274 | }); |
|
317 | }); |
@@ -584,7 +584,7 b' casper.dashboard_test = function (test) {' | |||||
584 |
|
584 | |||
585 | // note that this will only work for UNIQUE events -- if you want to |
|
585 | // note that this will only work for UNIQUE events -- if you want to | |
586 | // listen for the same event twice, this will not work! |
|
586 | // listen for the same event twice, this will not work! | |
587 | casper.event_test = function (name, events, action) { |
|
587 | casper.event_test = function (name, events, action, timeout) { | |
588 |
|
588 | |||
589 | // set up handlers to listen for each of the events |
|
589 | // set up handlers to listen for each of the events | |
590 | this.thenEvaluate(function (events) { |
|
590 | this.thenEvaluate(function (events) { | |
@@ -611,7 +611,7 b' casper.event_test = function (name, events, action) {' | |||||
611 | return this.evaluate(function (events) { |
|
611 | return this.evaluate(function (events) { | |
612 | return IPython._events_triggered.length >= events.length; |
|
612 | return IPython._events_triggered.length >= events.length; | |
613 | }, [events]); |
|
613 | }, [events]); | |
614 | }); |
|
614 | }, undefined, undefined, timeout); | |
615 |
|
615 | |||
616 | // test that the events were triggered in the proper order |
|
616 | // test that the events were triggered in the proper order | |
617 | this.then(function () { |
|
617 | this.then(function () { |
General Comments 0
You need to be logged in to leave comments.
Login now