Make User not a HasTraits

HasTraits are expensive to instantiate, so make Users as light as possible

Removes immediate instantiation of Spawners during User init. Spawners will only be instantiated while running
This commit is contained in:
Min RK
2018-02-06 11:32:26 +01:00
parent fb3bc95623
commit 0c6aa064ac
2 changed files with 34 additions and 41 deletions

View File

@@ -1265,9 +1265,11 @@ class JupyterHub(Application):
orm_user = orm_spawner.user orm_user = orm_spawner.user
user = self.users.add(orm_user) user = self.users.add(orm_user)
self.log.debug("Loading state for %s from db", user.name) self.log.debug("Loading state for %s from db", user.name)
for name, spawner in user.spawners.items(): for name, orm_spawner in user.orm_spawners.items():
f = check_spawner(user, name, spawner) if orm_spawner.server is not None:
check_futures.append(f) spawner = user.spawners[name]
f = check_spawner(user, name, spawner)
check_futures.append(f)
# await checks after submitting them all # await checks after submitting them all
yield gen.multi(check_futures) yield gen.multi(check_futures)

View File

@@ -127,23 +127,38 @@ class _SpawnerDict(dict):
return super().__getitem__(key) return super().__getitem__(key)
class User(HasTraits): class User:
"""High-level wrapper around an orm.User object"""
@default('log') # declare instance attributes
def _log_default(self): db = None
return app_log orm_user = None
log = app_log
settings = None
spawners = None def __init__(self, orm_user, settings=None, **kwargs):
settings = Dict() self.orm_user = orm_user
self.db = inspect(orm_user).session
self.settings = settings or {}
for key, attr in kwargs:
print('setting', key, attr)
setattr(self, key, attr)
db = Any(allow_none=True)
@default('db') self.allow_named_servers = self.settings.get('allow_named_servers', False)
def _db_default(self):
if self.orm_user:
return inspect(self.orm_user).session
orm_user = Any(allow_none=True) self.base_url = self.prefix = url_path_join(
self.settings.get('base_url', '/'), 'user', self.escaped_name) + '/'
self.spawners = _SpawnerDict(self._new_spawner)
@property
def authenticator(self):
return self.settings.get('authenticator', None)
@property
def spawner_class(self):
return self.settings.get('spawner_class', LocalProcessSpawner)
@gen.coroutine @gen.coroutine
def save_auth_state(self, auth_state): def save_auth_state(self, auth_state):
@@ -174,30 +189,6 @@ class User(HasTraits):
yield self.save_auth_state(auth_state) yield self.save_auth_state(auth_state)
return auth_state return auth_state
@property
def authenticator(self):
return self.settings.get('authenticator', None)
@property
def spawner_class(self):
return self.settings.get('spawner_class', LocalProcessSpawner)
def __init__(self, orm_user, settings=None, **kwargs):
if settings:
kwargs['settings'] = settings
kwargs['orm_user'] = orm_user
super().__init__(**kwargs)
self.allow_named_servers = self.settings.get('allow_named_servers', False)
self.base_url = self.prefix = url_path_join(
self.settings.get('base_url', '/'), 'user', self.escaped_name) + '/'
self.spawners = _SpawnerDict(self._new_spawner)
# load existing named spawners
for name in self.orm_spawners:
self.spawners[name] = self._new_spawner(name)
def _new_spawner(self, name, spawner_class=None, **kwargs): def _new_spawner(self, name, spawner_class=None, **kwargs):
"""Create a new spawner""" """Create a new spawner"""
if spawner_class is None: if spawner_class is None: