diff --git a/IPython/frontend/html/notebook/handlers.py b/IPython/frontend/html/notebook/handlers.py
index b3a594e..85df1b8 100644
--- a/IPython/frontend/html/notebook/handlers.py
+++ b/IPython/frontend/html/notebook/handlers.py
@@ -479,6 +479,8 @@ class IOPubHandler(AuthenticatedZMQStreamHandler):
return
km = self.application.kernel_manager
kernel_id = self.kernel_id
+ km.add_restart_callback(kernel_id, self.on_kernel_restarted)
+ km.add_restart_callback(kernel_id, self.on_restart_failed, 'dead')
try:
self.iopub_stream = km.connect_iopub(kernel_id)
except web.HTTPError:
@@ -493,10 +495,31 @@ class IOPubHandler(AuthenticatedZMQStreamHandler):
def on_message(self, msg):
pass
+ def _send_status_message(self, status):
+ msg = self.session.msg("status",
+ {'execution_state': status}
+ )
+ self.write_message(jsonapi.dumps(msg, default=date_default))
+
+ def on_kernel_restarted(self):
+ logging.warn("kernel %s restarted", self.kernel_id)
+ self._send_status_message('restarting')
+
+ def on_restart_failed(self):
+ logging.error("kernel %s restarted failed!", self.kernel_id)
+ self._send_status_message('dead')
+
def on_close(self):
# This method can be called twice, once by self.kernel_died and once
# from the WebSocket close event. If the WebSocket connection is
# closed before the ZMQ streams are setup, they could be None.
+ km = self.application.kernel_manager
+ km.remove_restart_callback(
+ self.kernel_id, self.on_kernel_restarted,
+ )
+ km.remove_restart_callback(
+ self.kernel_id, self.on_restart_failed, 'dead',
+ )
if self.iopub_stream is not None and not self.iopub_stream.closed():
self.iopub_stream.on_recv(None)
self.iopub_stream.close()