From adda2fcd9070f6a22e85e519a222e9c58751a5ad Mon Sep 17 00:00:00 2001 From: Min RK Date: Fri, 21 Oct 2016 16:28:40 +0200 Subject: [PATCH] Don't assume empty state means not running Some Spawners may not need state, and they should be allowed to resume on Hub restart as well. Adds some detail about when .poll may be called and how it should behave in less obvious circumstances --- jupyterhub/app.py | 5 ----- jupyterhub/spawner.py | 16 +++++++++++++++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/jupyterhub/app.py b/jupyterhub/app.py index 9d25aa60..8e37b63e 100644 --- a/jupyterhub/app.py +++ b/jupyterhub/app.py @@ -1058,11 +1058,6 @@ class JupyterHub(Application): for orm_user in db.query(orm.User): self.users[orm_user.id] = user = User(orm_user, self.tornado_settings) - if not user.state: - # without spawner state, server isn't valid - user.server = None - user_summaries.append(_user_summary(user)) - continue self.log.debug("Loading state for %s from db", user.name) spawner = user.spawner status = yield spawner.poll() diff --git a/jupyterhub/spawner.py b/jupyterhub/spawner.py index 8fea1384..12610919 100644 --- a/jupyterhub/spawner.py +++ b/jupyterhub/spawner.py @@ -191,7 +191,7 @@ class Spawner(LoggingConfigurable): def load_state(self, state): """load state from the database - This is the extensible part of state + This is the extensible part of state. Override in a subclass if there is state to load. Should call `super`. @@ -351,6 +351,20 @@ class Spawner(LoggingConfigurable): """Check if the single-user process is running return None if it is, an exit status (0 if unknown) if it is not. + If the Spawner has not been initialized (neither loaded state, nor called start), + it should behave as if it is not running (status=0). + If the Spawner has not finished starting, + it should behave as if it is running (status=None). + + Assumptions about poll and when it can be called: + + - poll may be called before start when state is loaded on Hub restart. + It should return 0 if the Spawner has not been initialized + via either load_state or start. + - If `.start()` is async, poll may be called during any yielded + portions of start. It should return None in this condition, + indicating that the process has not yet exited. + """ raise NotImplementedError("Override in subclass. Must be a Tornado gen.coroutine.")