# retoor import json import threading import time from datetime import datetime, timedelta, timezone from molodetz import config from molodetz.database import db, get_service_state, now_iso, update_user _lock = threading.Lock() _last_write = {} def touch(uid): if not uid: return now = time.monotonic() throttle = max(1, config.PRESENCE_TIMEOUT_SECONDS // 2) with _lock: if now - _last_write.get(uid, 0) < throttle: return _last_write[uid] = now update_user(uid, last_seen_at=now_iso()) def compute_roster(): if "users" not in db.tables: return [] window = config.PRESENCE_TIMEOUT_SECONDS + config.PRESENCE_ONLINE_MARGIN_SECONDS cutoff = (datetime.now(timezone.utc) - timedelta(seconds=window)).isoformat() rows = db.query( "SELECT uid FROM users WHERE last_seen_at >= :cutoff AND deleted_at IS NULL " "ORDER BY last_seen_at DESC LIMIT :limit", cutoff=cutoff, limit=config.PRESENCE_TRACK_LIMIT, ) return [row["uid"] for row in rows] def published_roster(): row = get_service_state("presence") if row and row.get("metrics"): try: metrics = json.loads(row["metrics"]) except ValueError: metrics = {} if "roster" in metrics: return metrics["roster"] return compute_roster() def online_uids(limit=None): return published_roster()[: limit or config.PRESENCE_ONLINE_LIMIT]