new functions
This commit is contained in:
@@ -13,6 +13,8 @@ CACHE_SECONDS = 15 * 60
|
||||
_STARTUP_DELAY_SECONDS = 3 * 60
|
||||
_STARTED_AT = time.monotonic()
|
||||
_LOCK = threading.Lock()
|
||||
_BACKGROUND_LOCK = threading.Lock()
|
||||
_BACKGROUND_PROFILE_IDS: set[int] = set()
|
||||
|
||||
|
||||
def _human_size(value: int | float) -> str:
|
||||
@@ -167,3 +169,39 @@ def maybe_refresh(profile: dict | None, force: bool = False) -> dict[str, Any] |
|
||||
return get(profile, force=True)
|
||||
except Exception:
|
||||
return cached
|
||||
|
||||
|
||||
def queue_refresh(socketio, profile: dict | None, force: bool = False, emit_update: bool = True) -> dict[str, Any] | None:
|
||||
"""Schedule heavier statistics refresh outside the main WebSocket/system poller."""
|
||||
if not profile:
|
||||
return None
|
||||
if not force and time.monotonic() - _STARTED_AT < _STARTUP_DELAY_SECONDS:
|
||||
return _load_cached(int(profile.get("id") or 0))
|
||||
|
||||
profile_id = int(profile.get("id") or 0)
|
||||
cached = _load_cached(profile_id)
|
||||
if cached and not cached.get("stale") and not force:
|
||||
return cached
|
||||
|
||||
with _BACKGROUND_LOCK:
|
||||
if profile_id in _BACKGROUND_PROFILE_IDS:
|
||||
return cached
|
||||
_BACKGROUND_PROFILE_IDS.add(profile_id)
|
||||
|
||||
profile_snapshot = dict(profile)
|
||||
|
||||
def runner():
|
||||
try:
|
||||
# Note: This can query file metadata per torrent, so it never runs inside the fast CPU/RAM/disk poller.
|
||||
stats = get(profile_snapshot, force=True)
|
||||
if emit_update and stats:
|
||||
socketio.emit("torrent_stats_update", {"profile_id": profile_id, "stats": stats})
|
||||
except Exception as exc:
|
||||
if emit_update:
|
||||
socketio.emit("torrent_stats_update", {"profile_id": profile_id, "ok": False, "error": str(exc)})
|
||||
finally:
|
||||
with _BACKGROUND_LOCK:
|
||||
_BACKGROUND_PROFILE_IDS.discard(profile_id)
|
||||
|
||||
socketio.start_background_task(runner)
|
||||
return cached
|
||||
|
||||
Reference in New Issue
Block a user