diff --git a/jupyterhub/app.py b/jupyterhub/app.py index 71e3ceb8..2d898dad 100644 --- a/jupyterhub/app.py +++ b/jupyterhub/app.py @@ -1449,11 +1449,14 @@ class JupyterHub(Application): routes = yield self.proxy.get_all_routes() users_count = 0 active_users_count = 0 + now = datetime.utcnow() for prefix, route in routes.items(): route_data = route['data'] if 'user' not in route_data: # not a user route, ignore it continue + if 'server_name' not in route_data: + continue users_count += 1 if 'last_activity' not in route_data: # no last activity data (possibly proxy other than CHP) @@ -1462,13 +1465,18 @@ class JupyterHub(Application): if user is None: self.log.warning("Found no user for route: %s", route) continue + spawner = user.orm_spawners.get(route_data['server_name']) + if spawner is None: + self.log.warning("Found no spawner for route: %s", route) + continue try: dt = datetime.strptime(route_data['last_activity'], ISO8601_ms) except Exception: dt = datetime.strptime(route_data['last_activity'], ISO8601_s) user.last_activity = max(user.last_activity, dt) + spawner.last_activity = max(spawner.last_activity, dt) # FIXME: Make this configurable duration. 30 minutes for now! - if (datetime.now() - user.last_activity).total_seconds() < 30 * 60: + if (now - user.last_activity).total_seconds() < 30 * 60: active_users_count += 1 self.statsd.gauge('users.running', users_count) self.statsd.gauge('users.active', active_users_count) diff --git a/jupyterhub/orm.py b/jupyterhub/orm.py index 8516cd97..b6d077f7 100644 --- a/jupyterhub/orm.py +++ b/jupyterhub/orm.py @@ -65,16 +65,13 @@ class Server(Base): """ __tablename__ = 'servers' id = Column(Integer, primary_key=True) - + proto = Column(Unicode(15), default='http') ip = Column(Unicode(255), default='') # could also be a DNS name port = Column(Integer, default=random_port) base_url = Column(Unicode(255), default='/') cookie_name = Column(Unicode(255), default='cookie') - # added to handle multi-server feature - last_activity = Column(DateTime, default=datetime.utcnow) - def __repr__(self): return "" % (self.ip, self.port) @@ -186,6 +183,8 @@ class Spawner(Base): state = Column(JSONDict) name = Column(Unicode(512)) + last_activity = Column(DateTime, default=datetime.utcnow) + class Service(Base): """A service run with JupyterHub diff --git a/jupyterhub/user.py b/jupyterhub/user.py index baa92664..00f6ac68 100644 --- a/jupyterhub/user.py +++ b/jupyterhub/user.py @@ -414,7 +414,7 @@ class User(HasTraits): if self.state is None: self.state = {} spawner.orm_spawner.state = spawner.get_state() - self.last_activity = datetime.utcnow() + self.last_activity = spawner.orm_spawner.last_activity = datetime.utcnow() db.commit() spawner._waiting_for_response = True try: @@ -468,7 +468,7 @@ class User(HasTraits): yield spawner.stop() spawner.clear_state() spawner.orm_spawner.state = spawner.get_state() - self.last_activity = datetime.utcnow() + self.last_activity = spawner.orm_spawner.last_activity = datetime.utcnow() # remove server entry from db spawner.server = None if not spawner.will_resume: