##// END OF EJS Templates
Cleaned up frontend-level kernel restart logic.
epatters -
Show More
@@ -268,15 +268,22 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 """
274 if keep_input:
275 input_buffer = self.input_buffer
276 self._control.clear()
277 self._show_prompt()
278 if keep_input:
279 self.input_buffer = input_buffer
278 if self._executing:
279 self._control.clear()
280 else:
281 if keep_input:
282 input_buffer = self.input_buffer
283 self._control.clear()
284 self._show_prompt()
285 if keep_input:
286 self.input_buffer = input_buffer
280 287
281 288 def copy(self):
282 289 """ Copy the currently selected text to the clipboard.
@@ -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 """
322 message = 'The kernel heartbeat has been inactive for %.2f ' \
323 'seconds. Do you want to restart the kernel? You may ' \
324 'first want to check the network connection.' % \
325 since_last_heartbeat
326 321 if self.custom_restart:
327 322 self.custom_restart_kernel_died.emit(since_last_heartbeat)
328 323 else:
324 message = 'The kernel heartbeat has been inactive for %.2f ' \
325 'seconds. Do you want to restart the kernel? You may ' \
326 'first want to check the network connection.' % \
327 since_last_heartbeat
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,45 +389,56 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:
417 if self.custom_restart:
418 self.custom_restart_requested.emit()
419 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
423 buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
424 result = QtGui.QMessageBox.question(self, 'Restart kernel?',
425 message, buttons)
426 if result == QtGui.QMessageBox.Yes:
427 try:
428 self.kernel_manager.restart_kernel(now=now)
429 except RuntimeError:
430 message = 'Kernel started externally. Cannot restart.\n'
431 self._append_plain_text(message)
432 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
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
415 if self.custom_restart:
416 self.custom_restart_requested.emit()
417
418 elif self.kernel_manager.has_kernel:
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.)
425 buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
426 result = QtGui.QMessageBox.question(self, 'Restart kernel?',
427 message, buttons)
428 if result == QtGui.QMessageBox.Yes:
429 try:
430 self.kernel_manager.restart_kernel(now=now)
431 except RuntimeError:
432 self._append_plain_text('Kernel started externally. '
433 'Cannot restart.\n')
434 else:
435 self.reset()
438 436 else:
439 self._append_plain_text('Kernel process is either remote or '
440 'unspecified. Cannot restart.\n')
437 self.kernel_manager.hb_channel.unpause()
438
439 else:
440 self._append_plain_text('Kernel process is either remote or '
441 'unspecified. Cannot restart.\n')
441 442
442 443 #---------------------------------------------------------------------------
443 444 # 'FrontendWidget' protected interface
General Comments 0
You need to be logged in to leave comments. Login now