Show More
@@ -161,7 +161,7 b' class Kernel(Configurable):' | |||||
161 | for msg_type in msg_types: |
|
161 | for msg_type in msg_types: | |
162 | self.shell_handlers[msg_type] = getattr(self, msg_type) |
|
162 | self.shell_handlers[msg_type] = getattr(self, msg_type) | |
163 |
|
163 | |||
164 | control_msg_types = [ 'clear_request', 'abort_request' ] |
|
164 | control_msg_types = msg_types + [ 'clear_request', 'abort_request' ] | |
165 | self.control_handlers = {} |
|
165 | self.control_handlers = {} | |
166 | for msg_type in control_msg_types: |
|
166 | for msg_type in control_msg_types: | |
167 | self.control_handlers[msg_type] = getattr(self, msg_type) |
|
167 | self.control_handlers[msg_type] = getattr(self, msg_type) | |
@@ -480,14 +480,17 b' class Kernel(Configurable):' | |||||
480 |
|
480 | |||
481 | def shutdown_request(self, stream, ident, parent): |
|
481 | def shutdown_request(self, stream, ident, parent): | |
482 | self.shell.exit_now = True |
|
482 | self.shell.exit_now = True | |
|
483 | content = dict(status='ok') | |||
|
484 | content.update(parent['content']) | |||
|
485 | self.session.send(stream, u'shutdown_reply', content, parent, ident=ident) | |||
|
486 | # same content, but different msg_id for broadcasting on IOPub | |||
483 | self._shutdown_message = self.session.msg(u'shutdown_reply', |
|
487 | self._shutdown_message = self.session.msg(u'shutdown_reply', | |
484 |
|
|
488 | content, parent | |
485 | ) |
|
489 | ) | |
486 | # self.session.send(stream, self._shutdown_message, ident=ident) |
|
|||
487 |
|
490 | |||
488 | self._at_shutdown() |
|
491 | self._at_shutdown() | |
489 | # call sys.exit after a short delay |
|
492 | # call sys.exit after a short delay | |
490 |
ioloop.IOLoop.instance().add_timeout(time.time()+0. |
|
493 | ioloop.IOLoop.instance().add_timeout(time.time()+0.1, lambda : sys.exit(0)) | |
491 |
|
494 | |||
492 | #--------------------------------------------------------------------------- |
|
495 | #--------------------------------------------------------------------------- | |
493 | # Engine methods |
|
496 | # Engine methods | |
@@ -615,6 +618,8 b' class Kernel(Configurable):' | |||||
615 | self._abort_queue(stream) |
|
618 | self._abort_queue(stream) | |
616 |
|
619 | |||
617 | def _abort_queue(self, stream): |
|
620 | def _abort_queue(self, stream): | |
|
621 | poller = zmq.Poller() | |||
|
622 | poller.register(stream.socket, zmq.POLLIN) | |||
618 | while True: |
|
623 | while True: | |
619 | idents,msg = self.session.recv(stream, zmq.NOBLOCK, content=True) |
|
624 | idents,msg = self.session.recv(stream, zmq.NOBLOCK, content=True) | |
620 | if msg is None: |
|
625 | if msg is None: | |
@@ -632,7 +637,7 b' class Kernel(Configurable):' | |||||
632 | self.log.debug("%s", reply_msg) |
|
637 | self.log.debug("%s", reply_msg) | |
633 | # We need to wait a bit for requests to come in. This can probably |
|
638 | # We need to wait a bit for requests to come in. This can probably | |
634 | # be set shorter for true asynchronous clients. |
|
639 | # be set shorter for true asynchronous clients. | |
635 |
|
|
640 | poller.poll(50) | |
636 |
|
641 | |||
637 |
|
642 | |||
638 | def _no_raw_input(self): |
|
643 | def _no_raw_input(self): |
@@ -19,8 +19,12 b' from __future__ import print_function' | |||||
19 | import inspect |
|
19 | import inspect | |
20 | import os |
|
20 | import os | |
21 | import sys |
|
21 | import sys | |
|
22 | import time | |||
22 | from subprocess import Popen, PIPE |
|
23 | from subprocess import Popen, PIPE | |
23 |
|
24 | |||
|
25 | # System library imports | |||
|
26 | from zmq.eventloop import ioloop | |||
|
27 | ||||
24 | # Our own |
|
28 | # Our own | |
25 | from IPython.core.interactiveshell import ( |
|
29 | from IPython.core.interactiveshell import ( | |
26 | InteractiveShell, InteractiveShellABC |
|
30 | InteractiveShell, InteractiveShellABC | |
@@ -114,6 +118,12 b' class ZMQInteractiveShell(InteractiveShell):' | |||||
114 | exiter = Instance(ZMQExitAutocall) |
|
118 | exiter = Instance(ZMQExitAutocall) | |
115 | def _exiter_default(self): |
|
119 | def _exiter_default(self): | |
116 | return ZMQExitAutocall(self) |
|
120 | return ZMQExitAutocall(self) | |
|
121 | ||||
|
122 | def _exit_now_changed(self, name, old, new): | |||
|
123 | """stop eventloop when exit_now fires""" | |||
|
124 | if new: | |||
|
125 | loop = ioloop.IOLoop.instance() | |||
|
126 | loop.add_timeout(time.time()+0.1, loop.stop) | |||
117 |
|
127 | |||
118 | keepkernel_on_exit = None |
|
128 | keepkernel_on_exit = None | |
119 |
|
129 | |||
@@ -154,6 +164,7 b' class ZMQInteractiveShell(InteractiveShell):' | |||||
154 |
|
164 | |||
155 | def ask_exit(self): |
|
165 | def ask_exit(self): | |
156 | """Engage the exit actions.""" |
|
166 | """Engage the exit actions.""" | |
|
167 | self.exit_now = True | |||
157 | payload = dict( |
|
168 | payload = dict( | |
158 | source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit', |
|
169 | source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit', | |
159 | exit=True, |
|
170 | exit=True, |
General Comments 0
You need to be logged in to leave comments.
Login now