##// END OF EJS Templates
Interrupt and restart work for kernels.
Brian Granger -
Show More
@@ -38,10 +38,21 b' class KernelHandler(web.RequestHandler):'
38
38
39 def post(self):
39 def post(self):
40 kernel_id = self.application.start_kernel()
40 kernel_id = self.application.start_kernel()
41 self.application.start_session(kernel_id)
42 self.write(json.dumps(kernel_id))
41 self.write(json.dumps(kernel_id))
43
42
44
43
44 class KernelActionHandler(web.RequestHandler):
45
46 def get(self, kernel_id):
47 # TODO: figure out a better way of handling RPC style calls.
48 if self.request.arguments.has_key('interrupt'):
49 self.application.interrupt_kernel(kernel_id)
50 if self.request.arguments.has_key('restart'):
51 new_kernel_id = self.application.restart_kernel(kernel_id)
52 self.write(json.dumps(new_kernel_id))
53 logging.info(repr(self.request.arguments))
54
55
45 class ZMQStreamRouter(object):
56 class ZMQStreamRouter(object):
46
57
47 def __init__(self, zmq_stream):
58 def __init__(self, zmq_stream):
@@ -57,6 +68,12 b' class ZMQStreamRouter(object):'
57 def unregister_client(self, client_id):
68 def unregister_client(self, client_id):
58 del self._clients[client_id]
69 del self._clients[client_id]
59
70
71 def copy_clients(self, router):
72 # Copy the clients of another router.
73 for client_id, client in router._clients.items():
74 client.router = self
75 self._clients[client_id] = client
76
60
77
61 class IOPubStreamRouter(ZMQStreamRouter):
78 class IOPubStreamRouter(ZMQStreamRouter):
62
79
@@ -159,6 +176,7 b' class NotebookApplication(web.Application):'
159 handlers = [
176 handlers = [
160 (r"/", MainHandler),
177 (r"/", MainHandler),
161 (r"/kernels", KernelHandler),
178 (r"/kernels", KernelHandler),
179 (r"/kernels/%s/actions" % _kernel_id_regex, KernelActionHandler),
162 (r"/kernels/%s/iopub" % _kernel_id_regex, ZMQStreamHandler, dict(stream_name='iopub')),
180 (r"/kernels/%s/iopub" % _kernel_id_regex, ZMQStreamHandler, dict(stream_name='iopub')),
163 (r"/kernels/%s/shell" % _kernel_id_regex, ZMQStreamHandler, dict(stream_name='shell')),
181 (r"/kernels/%s/shell" % _kernel_id_regex, ZMQStreamHandler, dict(stream_name='shell')),
164 (r"/notebooks", NotebookRootHandler),
182 (r"/notebooks", NotebookRootHandler),
@@ -186,8 +204,37 b' class NotebookApplication(web.Application):'
186 def start_kernel(self):
204 def start_kernel(self):
187 kernel_id = self.kernel_manager.start_kernel()
205 kernel_id = self.kernel_manager.start_kernel()
188 logging.info("Kernel started: %s" % kernel_id)
206 logging.info("Kernel started: %s" % kernel_id)
207 self.start_session(kernel_id)
189 return kernel_id
208 return kernel_id
190
209
210 def interrupt_kernel(self, kernel_id):
211 self.kernel_manager.interrupt_kernel(kernel_id)
212 logging.info("Kernel interrupted: %s" % kernel_id)
213
214 def restart_kernel(self, kernel_id):
215 # Create the new kernel first so we can move the clients over.
216 new_kernel_id = self.start_kernel()
217
218 # Copy the clients over to the new routers.
219 old_iopub_router = self.get_router(kernel_id, 'iopub')
220 old_shell_router = self.get_router(kernel_id, 'shell')
221 new_iopub_router = self.get_router(new_kernel_id, 'iopub')
222 new_shell_router = self.get_router(new_kernel_id, 'shell')
223 new_iopub_router.copy_clients(old_iopub_router)
224 new_shell_router.copy_clients(old_shell_router)
225
226 # Now shutdown the old session and the kernel.
227 # TODO: This causes a hard crash in ZMQStream.close, which sets
228 # self.socket to None to hastily. We will need to fix this in PyZMQ
229 # itself. For now, we just leave the old kernel running :(
230 # sm = self.kernel_manager.get_session_manager(kernel_id)
231 # session_id = self._session_dict[kernel_id]
232 # sm.stop_session(session_id)
233 # self.kernel_manager.kill_kernel(kernel_id)
234
235 logging.info("Kernel restarted")
236 return new_kernel_id
237
191 def start_session(self, kernel_id):
238 def start_session(self, kernel_id):
192 sm = self.kernel_manager.get_session_manager(kernel_id)
239 sm = self.kernel_manager.get_session_manager(kernel_id)
193 session_id = sm.start_session()
240 session_id = sm.start_session()
@@ -102,7 +102,7 b' var Notebook = function (selector) {'
102 Notebook.prototype.bind_events = function () {
102 Notebook.prototype.bind_events = function () {
103 var that = this;
103 var that = this;
104 $(document).keydown(function (event) {
104 $(document).keydown(function (event) {
105 // console.log(event);
105 console.log(event);
106 if (event.which == 38 && event.shiftKey) {
106 if (event.which == 38 && event.shiftKey) {
107 event.preventDefault();
107 event.preventDefault();
108 that.select_prev();
108 that.select_prev();
@@ -758,12 +758,27 b' Kernel.prototype.execute = function (code) {'
758 user_expressions : {}
758 user_expressions : {}
759 };
759 };
760 var msg = this.get_msg("execute_request", content);
760 var msg = this.get_msg("execute_request", content);
761
762 this.shell_channel.send(JSON.stringify(msg));
761 this.shell_channel.send(JSON.stringify(msg));
763 return msg.header.msg_id;
762 return msg.header.msg_id;
764 }
763 }
765
764
766
765
766 Kernel.prototype.interrupt = function () {
767 $.get(this.kernel_url + "/actions?interrupt=true");
768 };
769
770
771 Kernel.prototype.restart = function () {
772 url = this.kernel_url + "/actions?restart=true"
773 var that = this;
774 $.getJSON(url, function (kernel_id) {
775 console.log("Kernel restarted: " + kernel_id);
776 that.kernel_id = kernel_id;
777 that.kernel_url = that.base_url + "/" + that.kernel_id;
778 });
779 };
780
781
767 //============================================================================
782 //============================================================================
768 // On document ready
783 // On document ready
769 //============================================================================
784 //============================================================================
@@ -784,7 +799,10 b' $(document).ready(function () {'
784 $("#menu_tabs").tabs();
799 $("#menu_tabs").tabs();
785
800
786 $("#help_toolbar").buttonset();
801 $("#help_toolbar").buttonset();
802
787 $("#kernel_toolbar").buttonset();
803 $("#kernel_toolbar").buttonset();
804 $("#interrupt_kernel").click(function () {IPYTHON.notebook.kernel.interrupt();});
805 $("#restart_kernel").click(function () {IPYTHON.notebook.kernel.restart();});
788
806
789 $("#move_cell").buttonset();
807 $("#move_cell").buttonset();
790 $("#move_up").button("option", "icons", {primary:"ui-icon-arrowthick-1-n"});
808 $("#move_up").button("option", "icons", {primary:"ui-icon-arrowthick-1-n"});
@@ -57,8 +57,8 b''
57 </div>
57 </div>
58 <div id="kernel_tab">
58 <div id="kernel_tab">
59 <span id="kernel_toolbar">
59 <span id="kernel_toolbar">
60 <button>Interrupt</button>
60 <button id="interrupt_kernel">Interrupt</button>
61 <button>Restart</button>
61 <button id="restart_kernel">Restart</button>
62 </span>
62 </span>
63 </div>
63 </div>
64 <div id="help_tab">
64 <div id="help_tab">
General Comments 0
You need to be logged in to leave comments. Login now