From f9d70057460bddf1bad84ef6d73fdf15afc2485a 2012-05-13 22:09:36 From: MinRK Date: 2012-05-13 22:09:36 Subject: [PATCH] fixup shutdown/exit now that we use IOLoop various modes of shutting down should now result in exiting the loop. --- diff --git a/IPython/zmq/ipkernel.py b/IPython/zmq/ipkernel.py index c9574ae..14d70d0 100755 --- a/IPython/zmq/ipkernel.py +++ b/IPython/zmq/ipkernel.py @@ -161,7 +161,7 @@ class Kernel(Configurable): for msg_type in msg_types: self.shell_handlers[msg_type] = getattr(self, msg_type) - control_msg_types = [ 'clear_request', 'abort_request' ] + control_msg_types = msg_types + [ 'clear_request', 'abort_request' ] self.control_handlers = {} for msg_type in control_msg_types: self.control_handlers[msg_type] = getattr(self, msg_type) @@ -480,14 +480,17 @@ class Kernel(Configurable): def shutdown_request(self, stream, ident, parent): self.shell.exit_now = True + content = dict(status='ok') + content.update(parent['content']) + self.session.send(stream, u'shutdown_reply', content, parent, ident=ident) + # same content, but different msg_id for broadcasting on IOPub self._shutdown_message = self.session.msg(u'shutdown_reply', - parent['content'], parent + content, parent ) - # self.session.send(stream, self._shutdown_message, ident=ident) self._at_shutdown() # call sys.exit after a short delay - ioloop.IOLoop.instance().add_timeout(time.time()+0.05, lambda : sys.exit(0)) + ioloop.IOLoop.instance().add_timeout(time.time()+0.1, lambda : sys.exit(0)) #--------------------------------------------------------------------------- # Engine methods @@ -615,6 +618,8 @@ class Kernel(Configurable): self._abort_queue(stream) def _abort_queue(self, stream): + poller = zmq.Poller() + poller.register(stream.socket, zmq.POLLIN) while True: idents,msg = self.session.recv(stream, zmq.NOBLOCK, content=True) if msg is None: @@ -632,7 +637,7 @@ class Kernel(Configurable): self.log.debug("%s", reply_msg) # We need to wait a bit for requests to come in. This can probably # be set shorter for true asynchronous clients. - time.sleep(0.05) + poller.poll(50) def _no_raw_input(self): diff --git a/IPython/zmq/zmqshell.py b/IPython/zmq/zmqshell.py index 56d777f..d787dcf 100644 --- a/IPython/zmq/zmqshell.py +++ b/IPython/zmq/zmqshell.py @@ -19,8 +19,12 @@ from __future__ import print_function import inspect import os import sys +import time from subprocess import Popen, PIPE +# System library imports +from zmq.eventloop import ioloop + # Our own from IPython.core.interactiveshell import ( InteractiveShell, InteractiveShellABC @@ -114,6 +118,12 @@ class ZMQInteractiveShell(InteractiveShell): exiter = Instance(ZMQExitAutocall) def _exiter_default(self): return ZMQExitAutocall(self) + + def _exit_now_changed(self, name, old, new): + """stop eventloop when exit_now fires""" + if new: + loop = ioloop.IOLoop.instance() + loop.add_timeout(time.time()+0.1, loop.stop) keepkernel_on_exit = None @@ -154,6 +164,7 @@ class ZMQInteractiveShell(InteractiveShell): def ask_exit(self): """Engage the exit actions.""" + self.exit_now = True payload = dict( source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit', exit=True,