Merge pull request #7149 from minrk/thread-nb

run test notebook server in thread
Thomas Kluyver 11 years ago
commit 4c62fd4210

@ -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()

@ -888,7 +888,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=' ')
@ -897,11 +897,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())
@ -1004,13 +1004,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'):

@ -78,7 +78,6 @@ class TestContentsManager(TestCase):
self.td = self._temp_dir.name
self.contents_manager = FileContentsManager(
root_dir=self.td,
log=logging.getLogger()
)
def tearDown(self):

@ -6,11 +6,12 @@ import sys
import time
import requests
from contextlib import contextmanager
from subprocess import Popen, STDOUT
from threading import Thread, Event
from unittest import TestCase
import nose
from tornado.ioloop import IOLoop
from ..notebookapp import NotebookApp
from IPython.utils.tempdir import TemporaryDirectory
MAX_WAITTIME = 30 # seconds to wait for notebook server to start
@ -50,35 +51,46 @@ class NotebookTestBase(TestCase):
@classmethod
def wait_until_dead(cls):
"""Wait for the server process to terminate after shutdown"""
for _ in range(int(MAX_WAITTIME/POLL_INTERVAL)):
if cls.notebook.poll() is not None:
return
time.sleep(POLL_INTERVAL)
raise TimeoutError("Undead notebook server")
cls.notebook_thread.join(timeout=MAX_WAITTIME)
if cls.notebook_thread.is_alive():
raise TimeoutError("Undead notebook server")
@classmethod
def setup_class(cls):
cls.ipython_dir = TemporaryDirectory()
cls.notebook_dir = TemporaryDirectory()
notebook_args = [
sys.executable, '-c',
'from IPython.html.notebookapp import launch_new_instance; launch_new_instance()',
'--port=%d' % cls.port,
'--port-retries=0', # Don't try any other ports
'--no-browser',
'--ipython-dir=%s' % cls.ipython_dir.name,
'--notebook-dir=%s' % cls.notebook_dir.name,
]
cls.notebook = Popen(notebook_args,
stdout=nose.iptest_stdstreams_fileno(),
stderr=STDOUT,
app = cls.notebook = NotebookApp(
port=cls.port,
port_retries=0,
open_browser=False,
ipython_dir=cls.ipython_dir.name,
notebook_dir=cls.notebook_dir.name,
)
# clear log handlers and propagate to root for nose to capture it
# needs to be redone after initialize, which reconfigures logging
app.log.propagate = True
app.log.handlers = []
app.initialize(argv=[])
app.log.propagate = True
app.log.handlers = []
started = Event()
def start_thread():
loop = IOLoop.current()
loop.add_callback(started.set)
try:
app.start()
finally:
# set the event, so failure to start doesn't cause a hang
started.set()
cls.notebook_thread = Thread(target=start_thread)
cls.notebook_thread.start()
started.wait()
cls.wait_until_alive()
@classmethod
def teardown_class(cls):
cls.notebook.terminate()
cls.notebook.stop()
cls.wait_until_dead()
cls.ipython_dir.cleanup()
cls.notebook_dir.cleanup()

Loading…
Cancel
Save