Merge pull request #552 from minrk/poll-and-notify

notice dead servers more often
This commit is contained in:
Min RK
2016-05-04 12:33:09 +02:00
3 changed files with 17 additions and 8 deletions

View File

@@ -161,8 +161,9 @@ class UserServerAPIHandler(APIHandler):
@admin_or_self @admin_or_self
def post(self, name): def post(self, name):
user = self.find_user(name) user = self.find_user(name)
if user.spawner: if user.running:
state = yield user.spawner.poll() # include notify, so that a server that died is noticed immediately
state = yield user.spawner.poll_and_notify()
if state is None: if state is None:
raise web.HTTPError(400, "%s's server is already running" % name) raise web.HTTPError(400, "%s's server is already running" % name)
@@ -180,7 +181,8 @@ class UserServerAPIHandler(APIHandler):
return return
if not user.running: if not user.running:
raise web.HTTPError(400, "%s's server is not running" % name) raise web.HTTPError(400, "%s's server is not running" % name)
status = yield user.spawner.poll() # include notify, so that a server that died is noticed immediately
status = yield user.spawner.poll_and_notify()
if status is not None: if status is not None:
raise web.HTTPError(400, "%s's server is not running" % name) raise web.HTTPError(400, "%s's server is not running" % name)
yield self.stop_single_user(user) yield self.stop_single_user(user)

View File

@@ -41,9 +41,14 @@ class HomeHandler(BaseHandler):
"""Render the user's home page.""" """Render the user's home page."""
@web.authenticated @web.authenticated
@gen.coroutine
def get(self): def get(self):
user = self.get_current_user()
if user.running:
# trigger poll_and_notify event in case of a server that died
yield user.spawner.poll_and_notify()
html = self.render_template('home.html', html = self.render_template('home.html',
user=self.get_current_user(), user=user,
) )
self.finish(html) self.finish(html)

View File

@@ -15,7 +15,7 @@ from subprocess import Popen
from tempfile import mkdtemp from tempfile import mkdtemp
from tornado import gen from tornado import gen
from tornado.ioloop import IOLoop, PeriodicCallback from tornado.ioloop import PeriodicCallback
from traitlets.config import LoggingConfigurable from traitlets.config import LoggingConfigurable
from traitlets import ( from traitlets import (
@@ -335,15 +335,17 @@ class Spawner(LoggingConfigurable):
self.stop_polling() self.stop_polling()
add_callback = IOLoop.current().add_callback
for callback in self._callbacks: for callback in self._callbacks:
add_callback(callback) try:
yield gen.maybe_future(callback())
except Exception:
self.log.exception("Unhandled error in poll callback for %s", self)
return status
death_interval = Float(0.1) death_interval = Float(0.1)
@gen.coroutine @gen.coroutine
def wait_for_death(self, timeout=10): def wait_for_death(self, timeout=10):
"""wait for the process to die, up to timeout seconds""" """wait for the process to die, up to timeout seconds"""
loop = IOLoop.current()
for i in range(int(timeout / self.death_interval)): for i in range(int(timeout / self.death_interval)):
status = yield self.poll() status = yield self.poll()
if status is not None: if status is not None: