Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 22 additions & 21 deletions backend_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ def _nile_env(prefix: str, base: Optional[Dict[str, str]] = None) -> Dict[str, s
_legendary_installs: Dict[str, Any] = {} # app_name -> (Popen, file, log_path, prefix)
_legendary_paused: Dict[str, str] = {} # app_name -> prefix (paused downloads)
_legendary_games_cache: Dict[str, Any] = {} # prefix -> {"games": [], "ts": float, "scanning": bool}
_legendary_cache_lock = threading.Lock()
_LEGENDARY_CACHE_TTL = 300 # seconds before a background re-fetch is triggered

# Download queue — one install runs at a time, others wait.
Expand Down Expand Up @@ -201,6 +202,7 @@ def _legendary_queue_worker() -> None:
_nile_installs: Dict[str, Any] = {} # amazon_id -> (Popen, file, log_path, prefix)
_nile_paused: Dict[str, str] = {} # amazon_id -> prefix (paused downloads)
_nile_games_cache: Dict[str, Any] = {} # prefix -> {"games": [], "ts": float, "scanning": bool}
_nile_cache_lock = threading.Lock()
_NILE_CACHE_TTL = 300 # seconds before a background re-fetch is triggered

# Download queue — one install runs at a time, others wait.
Expand Down Expand Up @@ -253,7 +255,8 @@ def _nile_do_install(amazon_id: str, prefix: str) -> None:
entry[1].close()
except Exception:
pass
_nile_games_cache.pop(prefix, None)
with _nile_cache_lock:
_nile_games_cache.pop(prefix, None)


def _nile_queue_worker() -> None:
Expand Down Expand Up @@ -7897,31 +7900,29 @@ def _scan_nile_games(prefix: str) -> List[Dict[str, Any]]:
if not _nile_installed():
return []

entry = _nile_games_cache.get(prefix)
now = time.time()
with _nile_cache_lock:
entry = _nile_games_cache.get(prefix)
if entry:
if not entry.get("scanning", False):
age = now - entry.get("ts", 0)
if age < _NILE_CACHE_TTL:
return entry["games"]
entry["scanning"] = True
threading.Thread(target=_refresh_nile_cache, args=(prefix,), daemon=True).start()
return entry["games"]

if entry:
if not entry.get("scanning", False):
age = now - entry.get("ts", 0)
if age < _NILE_CACHE_TTL:
return entry["games"] # fresh in-memory cache — instant
entry["scanning"] = True
owned_disk = _nile_read_disk_library(prefix)
with _nile_cache_lock:
if owned_disk:
games_fast = _nile_build_games_list(prefix, owned_disk)
_nile_games_cache[prefix] = {"games": games_fast, "ts": 0, "scanning": True}
threading.Thread(target=_refresh_nile_cache, args=(prefix,), daemon=True).start()
return entry["games"] # return whatever we have while scanning
return games_fast

# No in-memory cache — try disk cache for an instant first response.
owned_disk = _nile_read_disk_library(prefix)
if owned_disk:
games_fast = _nile_build_games_list(prefix, owned_disk)
_nile_games_cache[prefix] = {"games": games_fast, "ts": 0, "scanning": True}
_nile_games_cache[prefix] = {"games": [], "ts": 0, "scanning": True}
threading.Thread(target=_refresh_nile_cache, args=(prefix,), daemon=True).start()
return games_fast

# Truly cold start — nothing cached yet.
_nile_games_cache[prefix] = {"games": [], "ts": 0, "scanning": True}
threading.Thread(target=_refresh_nile_cache, args=(prefix,), daemon=True).start()
return []
return []
return []


def cmd_legendary_status(_params: Dict[str, Any]) -> Any:
Expand Down
Loading