##// END OF EJS Templates
Cleaned up frontend-level kernel restart logic.
epatters -
Show More
@@ -268,15 +268,22 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
268 return False
268 return False
269
269
270 def clear(self, keep_input=True):
270 def clear(self, keep_input=True):
271 """ Clear the console, then write a new prompt. If 'keep_input' is set,
271 """ Clear the console.
272 restores the old input buffer when the new prompt is written.
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:
278 if self._executing:
275 input_buffer = self.input_buffer
279 self._control.clear()
276 self._control.clear()
280 else:
277 self._show_prompt()
281 if keep_input:
278 if keep_input:
282 input_buffer = self.input_buffer
279 self.input_buffer = input_buffer
283 self._control.clear()
284 self._show_prompt()
285 if keep_input:
286 self.input_buffer = input_buffer
280
287
281 def copy(self):
288 def copy(self):
282 """ Copy the currently selected text to the clipboard.
289 """ Copy the currently selected text to the clipboard.
@@ -116,7 +116,6 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
116 self._highlighter = FrontendHighlighter(self)
116 self._highlighter = FrontendHighlighter(self)
117 self._input_splitter = self._input_splitter_class(input_mode='cell')
117 self._input_splitter = self._input_splitter_class(input_mode='cell')
118 self._kernel_manager = None
118 self._kernel_manager = None
119 self._possible_kernel_restart = False
120 self._request_info = {}
119 self._request_info = {}
121
120
122 # Configure the ConsoleWidget.
121 # Configure the ConsoleWidget.
@@ -319,13 +318,13 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
319 def _handle_kernel_died(self, since_last_heartbeat):
318 def _handle_kernel_died(self, since_last_heartbeat):
320 """ Handle the kernel's death by asking if the user wants to restart.
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 if self.custom_restart:
321 if self.custom_restart:
327 self.custom_restart_kernel_died.emit(since_last_heartbeat)
322 self.custom_restart_kernel_died.emit(since_last_heartbeat)
328 else:
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 self.restart_kernel(message, now=True)
328 self.restart_kernel(message, now=True)
330
329
331 def _handle_object_info_reply(self, rep):
330 def _handle_object_info_reply(self, rep):
@@ -361,16 +360,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
361 """ Called when the KernelManager channels have started listening or
360 """ Called when the KernelManager channels have started listening or
362 when the frontend is assigned an already listening KernelManager.
361 when the frontend is assigned an already listening KernelManager.
363 """
362 """
364 self._control.clear()
363 self.reset()
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
374
364
375 #---------------------------------------------------------------------------
365 #---------------------------------------------------------------------------
376 # 'FrontendWidget' public interface
366 # 'FrontendWidget' public interface
@@ -399,45 +389,56 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
399 self._append_plain_text('Kernel process is either remote or '
389 self._append_plain_text('Kernel process is either remote or '
400 'unspecified. Cannot interrupt.\n')
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 def restart_kernel(self, message, now=False):
406 def restart_kernel(self, message, now=False):
403 """ Attempts to restart the running kernel.
407 """ Attempts to restart the running kernel.
404 """
408 """
405 # FIXME: now should be configurable via a checkbox in the
409 # FIXME: now should be configurable via a checkbox in the dialog. Right
406 # dialog. Right now at least the heartbeat path sets it to True and
410 # now at least the heartbeat path sets it to True and the manual restart
407 # the manual restart to False. But those should just be the
411 # to False. But those should just be the pre-selected states of a
408 # pre-selected states of a checkbox that the user could override if so
412 # checkbox that the user could override if so desired. But I don't know
409 # desired. But I don't know enough Qt to go implementing the checkbox
413 # enough Qt to go implementing the checkbox now.
410 # now.
414
411
415 if self.custom_restart:
412 # We want to make sure that if this dialog is already happening, that
416 self.custom_restart_requested.emit()
413 # other signals don't trigger it again. This can happen when the
417
414 # kernel_died heartbeat signal is emitted and the user is slow to
418 elif self.kernel_manager.has_kernel:
415 # respond to the dialog.
419 # Pause the heart beat channel to prevent further warnings.
416 if not self._possible_kernel_restart:
420 self.kernel_manager.hb_channel.pause()
417 if self.custom_restart:
421
418 self.custom_restart_requested.emit()
422 # Prompt the user to restart the kernel. Un-pause the heartbeat if
419 elif self.kernel_manager.has_kernel:
423 # they decline. (If they accept, the heartbeat will be un-paused
420 # Setting this to True will prevent this logic from happening
424 # automatically when the kernel is restarted.)
421 # again until the current pass is completed.
425 buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
422 self._possible_kernel_restart = True
426 result = QtGui.QMessageBox.question(self, 'Restart kernel?',
423 buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
427 message, buttons)
424 result = QtGui.QMessageBox.question(self, 'Restart kernel?',
428 if result == QtGui.QMessageBox.Yes:
425 message, buttons)
429 try:
426 if result == QtGui.QMessageBox.Yes:
430 self.kernel_manager.restart_kernel(now=now)
427 try:
431 except RuntimeError:
428 self.kernel_manager.restart_kernel(now=now)
432 self._append_plain_text('Kernel started externally. '
429 except RuntimeError:
433 'Cannot restart.\n')
430 message = 'Kernel started externally. Cannot restart.\n'
434 else:
431 self._append_plain_text(message)
435 self.reset()
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
438 else:
436 else:
439 self._append_plain_text('Kernel process is either remote or '
437 self.kernel_manager.hb_channel.unpause()
440 'unspecified. Cannot restart.\n')
438
439 else:
440 self._append_plain_text('Kernel process is either remote or '
441 'unspecified. Cannot restart.\n')
441
442
442 #---------------------------------------------------------------------------
443 #---------------------------------------------------------------------------
443 # 'FrontendWidget' protected interface
444 # 'FrontendWidget' protected interface
General Comments 0
You need to be logged in to leave comments. Login now