aboutsummaryrefslogtreecommitdiff
path: root/app/backends/__init__.py
diff options
context:
space:
mode:
authorhistoria <historiavg@proton.me>2026-08-26 03:02:23 -0400
committerhistoria <historiavg@proton.me>2026-08-26 03:02:23 -0400
commitc147087c9d4707bffaeee58d390653637a21cce8 (patch)
treeb080c40eaa388609dea38c2cc413cb912aa7b4af /app/backends/__init__.py
parent8b5c8697740ff415cf7f1d03c9fb5a8c8851d420 (diff)
downloadtts-audiobook-generator-c147087c9d4707bffaeee58d390653637a21cce8.tar.gz
refactor: put shared ui screen code into ui.viewkit
Diffstat (limited to 'app/backends/__init__.py')
-rw-r--r--app/backends/__init__.py42
1 files changed, 39 insertions, 3 deletions
diff --git a/app/backends/__init__.py b/app/backends/__init__.py
index f6a1d9b..2b7fbe6 100644
--- a/app/backends/__init__.py
+++ b/app/backends/__init__.py
@@ -25,10 +25,17 @@ registry.
"""
import shlex
+import time
from dataclasses import dataclass, field
from pathlib import Path
from typing import Callable, Dict, List, Optional
+# How long detect_all() results stay fresh (see detect_all). Long enough to
+# cover a burst of menu renders, short enough that state changed by an
+# outside actor (a remote server appearing) surfaces promptly.
+DETECT_TTL_SECONDS = 2.0
+_detect_cache = None
+
@dataclass
class ServerSpec:
@@ -200,10 +207,39 @@ def get(key: str) -> Optional[BackendInfo]:
return _BY_KEY.get(key)
-def detect_all() -> List[BackendStatus]:
- """Detect every registered backend's status, in registry order."""
+def detect_all(*, refresh: bool = False) -> List[BackendStatus]:
+ """Detect every registered backend's status, in registry order.
+
+ Detection is not free — each backend probes the filesystem and, for
+ remote servers, the network — so results are cached for a short
+ window (DETECT_TTL_SECONDS). Menu renders that happen in quick
+ succession (popping back and forth between hub screens) reuse the
+ cached statuses; anything past the TTL re-probes. REFRESH forces an
+ immediate re-detection: callers use it right after an action that can
+ change status (setup, uninstall, server start/stop) so the next render
+ never shows stale state.
+ """
_build_registry()
- return [info.detect() for info in REGISTRY]
+ global _detect_cache
+ now = time.monotonic()
+ if not refresh and _detect_cache is not None:
+ at, statuses = _detect_cache
+ if now - at < DETECT_TTL_SECONDS:
+ return list(statuses)
+ statuses = [info.detect() for info in REGISTRY]
+ _detect_cache = (now, statuses)
+ return list(statuses)
+
+
+def invalidate_detect_cache() -> None:
+ """Drop the cached statuses so the next detect_all() re-probes.
+
+ Called by the hub after any action that can change a backend's on-disk
+ or running state (setup wizards, uninstallers, server toggles,
+ conversion runs with autostart, settings writes).
+ """
+ global _detect_cache
+ _detect_cache = None
def detect(key: str) -> Optional[BackendStatus]: