Don't add users with spawn_pending to the proxy

check_routes checks for missing routes for running users.
This is meant for when the proxy has been relaunched outside the Hub.

If spawners are slow to start, it's possible for check_routes to fire in the middle of spawning,
triggering addition of the user's server (which has no defined location yet) to the proxy before it's up.
If the spawning fails, the route will remain indefinitely (because it never should have been added in the first place), and the user will see 503 until their server is launched manually again.

Checking `spawn_pending` in user.running prevents this.
This commit is contained in:
Min RK
2016-03-01 15:18:51 +01:00
parent 5ec05822f1
commit f565f8ac53
2 changed files with 9 additions and 1 deletions

View File

@@ -178,6 +178,9 @@ class Proxy(Base):
self.log.info("Adding user %s to proxy %s => %s", self.log.info("Adding user %s to proxy %s => %s",
user.name, user.proxy_path, user.server.host, user.name, user.proxy_path, user.server.host,
) )
if user.spawn_pending:
raise RuntimeError(
"User %s's spawn is pending, shouldn't be added to the proxy yet!", user.name)
yield self.api_request(user.proxy_path, yield self.api_request(user.proxy_path,
method='POST', method='POST',
@@ -213,7 +216,7 @@ class Proxy(Base):
futures = [] futures = []
for orm_user in db.query(User): for orm_user in db.query(User):
user = user_dict[orm_user] user = user_dict[orm_user]
if (user.server): if user.running:
futures.append(self.add_user(user)) futures.append(self.add_user(user))
# wait after submitting them all # wait after submitting them all
for f in futures: for f in futures:
@@ -230,6 +233,9 @@ class Proxy(Base):
db = inspect(self).session db = inspect(self).session
for orm_user in db.query(User).filter(User.server != None): for orm_user in db.query(User).filter(User.server != None):
user = user_dict[orm_user] user = user_dict[orm_user]
if not user.running:
# Don't add users to the proxy that haven't finished starting
continue
if user.server is None: if user.server is None:
# This should never be True, but seems to be on rare occasion. # This should never be True, but seems to be on rare occasion.
# catch filter bug, either in sqlalchemy or my understanding of its behavior # catch filter bug, either in sqlalchemy or my understanding of its behavior

View File

@@ -145,6 +145,8 @@ class User(HasTraits):
@property @property
def running(self): def running(self):
"""property for whether a user has a running server""" """property for whether a user has a running server"""
if self.spawn_pending:
return False # server is not running if spawn is still pending
if self.server is None: if self.server is None:
return False return False
return True return True