##// END OF EJS Templates
Cleaned up frontend-level kernel restart logic.
epatters -
Show More
@@ -268,9 +268,16 class ConsoleWidget(Configurable, QtGui.QWidget):
268 268 return False
269 269
270 270 def clear(self, keep_input=True):
271 """ Clear the console, then write a new prompt. If 'keep_input' is set,
272 restores the old input buffer when the new prompt is written.
271 """ Clear the console.
272
273 Parameters:
274 -----------
275 keep_input : bool, optional (default True)
276 If set, restores the old input buffer if a new prompt is written.
273 277 """
278 if self._executing:
279 self._control.clear()
280 else:
274 281 if keep_input:
275 282 input_buffer = self.input_buffer
276 283 self._control.clear()
@@ -116,7 +116,6 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
116 116 self._highlighter = FrontendHighlighter(self)
117 117 self._input_splitter = self._input_splitter_class(input_mode='cell')
118 118 self._kernel_manager = None
119 self._possible_kernel_restart = False
120 119 self._request_info = {}
121 120
122 121 # Configure the ConsoleWidget.
@@ -319,13 +318,13 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
319 318 def _handle_kernel_died(self, since_last_heartbeat):
320 319 """ Handle the kernel's death by asking if the user wants to restart.
321 320 """
321 if self.custom_restart:
322 self.custom_restart_kernel_died.emit(since_last_heartbeat)
323 else:
322 324 message = 'The kernel heartbeat has been inactive for %.2f ' \
323 325 'seconds. Do you want to restart the kernel? You may ' \
324 326 'first want to check the network connection.' % \
325 327 since_last_heartbeat
326 if self.custom_restart:
327 self.custom_restart_kernel_died.emit(since_last_heartbeat)
328 else:
329 328 self.restart_kernel(message, now=True)
330 329
331 330 def _handle_object_info_reply(self, rep):
@@ -361,16 +360,7 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
361 360 """ Called when the KernelManager channels have started listening or
362 361 when the frontend is assigned an already listening KernelManager.
363 362 """
364 self._control.clear()
365 self._append_plain_text(self._get_banner())
366 self._show_interpreter_prompt()
367
368 def _stopped_channels(self):
369 """ Called when the KernelManager channels have stopped listening or
370 when a listening KernelManager is removed from the frontend.
371 """
372 self._executing = self._reading = False
373 self._highlighter.highlighting_on = False
363 self.reset()
374 364
375 365 #---------------------------------------------------------------------------
376 366 # 'FrontendWidget' public interface
@@ -399,27 +389,39 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
399 389 self._append_plain_text('Kernel process is either remote or '
400 390 'unspecified. Cannot interrupt.\n')
401 391
392 def reset(self):
393 """ Resets the widget to its initial state. Similar to ``clear``, but
394 also re-writes the banner and aborts execution if necessary.
395 """
396 if self._executing:
397 self._executing = False
398 self._request_info['execute'] = None
399 self._reading = False
400 self._highlighter.highlighting_on = False
401
402 self._control.clear()
403 self._append_plain_text(self._get_banner())
404 self._show_interpreter_prompt()
405
402 406 def restart_kernel(self, message, now=False):
403 407 """ Attempts to restart the running kernel.
404 408 """
405 # FIXME: now should be configurable via a checkbox in the
406 # dialog. Right now at least the heartbeat path sets it to True and
407 # the manual restart to False. But those should just be the
408 # pre-selected states of a checkbox that the user could override if so
409 # desired. But I don't know enough Qt to go implementing the checkbox
410 # now.
411
412 # We want to make sure that if this dialog is already happening, that
413 # other signals don't trigger it again. This can happen when the
414 # kernel_died heartbeat signal is emitted and the user is slow to
415 # respond to the dialog.
416 if not self._possible_kernel_restart:
409 # FIXME: now should be configurable via a checkbox in the dialog. Right
410 # now at least the heartbeat path sets it to True and the manual restart
411 # to False. But those should just be the pre-selected states of a
412 # checkbox that the user could override if so desired. But I don't know
413 # enough Qt to go implementing the checkbox now.
414
417 415 if self.custom_restart:
418 416 self.custom_restart_requested.emit()
417
419 418 elif self.kernel_manager.has_kernel:
420 # Setting this to True will prevent this logic from happening
421 # again until the current pass is completed.
422 self._possible_kernel_restart = True
419 # Pause the heart beat channel to prevent further warnings.
420 self.kernel_manager.hb_channel.pause()
421
422 # Prompt the user to restart the kernel. Un-pause the heartbeat if
423 # they decline. (If they accept, the heartbeat will be un-paused
424 # automatically when the kernel is restarted.)
423 425 buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
424 426 result = QtGui.QMessageBox.question(self, 'Restart kernel?',
425 427 message, buttons)
@@ -427,14 +429,13 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
427 429 try:
428 430 self.kernel_manager.restart_kernel(now=now)
429 431 except RuntimeError:
430 message = 'Kernel started externally. Cannot restart.\n'
431 self._append_plain_text(message)
432 self._append_plain_text('Kernel started externally. '
433 'Cannot restart.\n')
432 434 else:
433 self._stopped_channels()
434 self._append_plain_text('Kernel restarting...\n')
435 self._show_interpreter_prompt()
436 # This might need to be moved to another location?
437 self._possible_kernel_restart = False
435 self.reset()
436 else:
437 self.kernel_manager.hb_channel.unpause()
438
438 439 else:
439 440 self._append_plain_text('Kernel process is either remote or '
440 441 'unspecified. Cannot restart.\n')
General Comments 0
You need to be logged in to leave comments. Login now