From 89c7e8de0bd13deb5b55b4e90ecc69b1298377f1 2014-12-08 23:47:56
From: MinRK <benjaminrk@gmail.com>
Date: 2014-12-08 23:47:56
Subject: [PATCH] use IOLoop.current in a few places

better allow notebook server to run in a thread
---

diff --git a/IPython/html/base/zmqhandlers.py b/IPython/html/base/zmqhandlers.py
index 7eec55b..6f5b302 100644
--- a/IPython/html/base/zmqhandlers.py
+++ b/IPython/html/base/zmqhandlers.py
@@ -229,9 +229,12 @@ class AuthenticatedZMQStreamHandler(ZMQStreamHandler, IPythonHandler):
         
         # start the pinging
         if self.ping_interval > 0:
-            self.last_ping = ioloop.IOLoop.instance().time()  # Remember time of last ping
+            loop = ioloop.IOLoop.current()
+            self.last_ping = loop.time()  # Remember time of last ping
             self.last_pong = self.last_ping
-            self.ping_callback = ioloop.PeriodicCallback(self.send_ping, self.ping_interval)
+            self.ping_callback = ioloop.PeriodicCallback(
+                self.send_ping, self.ping_interval, io_loop=loop,
+            )
             self.ping_callback.start()
 
     def send_ping(self):
@@ -242,7 +245,7 @@ class AuthenticatedZMQStreamHandler(ZMQStreamHandler, IPythonHandler):
         
         # check for timeout on pong.  Make sure that we really have sent a recent ping in
         # case the machine with both server and client has been suspended since the last ping.
-        now = ioloop.IOLoop.instance().time()
+        now = ioloop.IOLoop.current().time()
         since_last_pong = 1e3 * (now - self.last_pong)
         since_last_ping = 1e3 * (now - self.last_ping)
         if since_last_ping < 2*self.ping_interval and since_last_pong > self.ping_timeout:
@@ -254,4 +257,4 @@ class AuthenticatedZMQStreamHandler(ZMQStreamHandler, IPythonHandler):
         self.last_ping = now
 
     def on_pong(self, data):
-        self.last_pong = ioloop.IOLoop.instance().time()
+        self.last_pong = ioloop.IOLoop.current().time()
diff --git a/IPython/html/notebookapp.py b/IPython/html/notebookapp.py
index d69b274..452d3aa 100644
--- a/IPython/html/notebookapp.py
+++ b/IPython/html/notebookapp.py
@@ -886,7 +886,7 @@ class NotebookApp(BaseIPythonApplication):
             line = sys.stdin.readline()
             if line.lower().startswith('y') and 'n' not in line.lower():
                 self.log.critical("Shutdown confirmed")
-                ioloop.IOLoop.instance().stop()
+                ioloop.IOLoop.current().stop()
                 return
         else:
             print("No answer for 5s:", end=' ')
@@ -895,11 +895,11 @@ class NotebookApp(BaseIPythonApplication):
         # set it back to original SIGINT handler
         # use IOLoop.add_callback because signal.signal must be called
         # from main thread
-        ioloop.IOLoop.instance().add_callback(self._restore_sigint_handler)
+        ioloop.IOLoop.current().add_callback(self._restore_sigint_handler)
     
     def _signal_stop(self, sig, frame):
         self.log.critical("received signal %s, stopping", sig)
-        ioloop.IOLoop.instance().stop()
+        ioloop.IOLoop.current().stop()
 
     def _signal_info(self, sig, frame):
         print(self.notebook_info())
@@ -1002,13 +1002,21 @@ class NotebookApp(BaseIPythonApplication):
                 b = lambda : browser.open(url_path_join(self.connection_url, uri),
                                           new=2)
                 threading.Thread(target=b).start()
+        
+        self.io_loop = ioloop.IOLoop.current()
         try:
-            ioloop.IOLoop.instance().start()
+            self.io_loop.start()
         except KeyboardInterrupt:
             info("Interrupted...")
         finally:
             self.cleanup_kernels()
             self.remove_server_info_file()
+    
+    def stop(self):
+        def _stop():
+            self.http_server.stop()
+            self.io_loop.stop()
+        self.io_loop.add_callback(_stop)
 
 
 def list_running_servers(profile='default'):