Actualizar dominios a dashboardapi y dashboardv1

This commit is contained in:
Administrator
2026-08-29 12:21:21 -05:00
parent 191b5bb1ba
commit 54581c21ab
77 changed files with 7679 additions and 11728 deletions

View File

@@ -1,8 +1,5 @@
# backend/cache_manager.py
"""
Caché global en memoria con refresco en segundo plano.
Independiente de Streamlit. Mantiene los datos calientes para respuestas instantáneas.
"""
"""Caché global en memoria con refresco en segundo plano (igual que el dashboard de ventas)."""
import time
import threading
from typing import Any, Callable, Dict, Tuple
@@ -16,37 +13,25 @@ def _make_key(prefix: str, args: tuple) -> str:
return prefix + ":" + "|".join(str(a) for a in args)
def cache_get_or_set(prefix: str, args: tuple, loader: Callable[[], Any],
ttl: int = _DEFAULT_TTL) -> Any:
"""Devuelve el valor cacheado si está fresco; si no, lo calcula y guarda."""
def cache_get_or_set(prefix: str, args: tuple, loader: Callable[[], Any], ttl: int = _DEFAULT_TTL) -> Any:
key = _make_key(prefix, args)
now = time.time()
with _LOCK:
hit = _CACHE.get(key)
if hit and (now - hit[0] < ttl):
return hit[1]
# Calcular fuera del lock (puede tardar)
value = loader()
with _LOCK:
_CACHE[key] = (now, value)
return value
def cache_set(prefix: str, args: tuple, value: Any) -> None:
key = _make_key(prefix, args)
with _LOCK:
_CACHE[key] = (time.time(), value)
def cache_keys():
"""Lista las claves actualmente cacheadas (para refrescarlas sin vaciar)."""
with _LOCK:
return list(_CACHE.keys())
def cache_refresh_existing(loader_for_key):
"""Recalcula SOLO las entradas que ya existen, sin vaciar el caché.
Así los meses ya visitados se mantienen calientes y nunca quedan 'fríos'."""
for key in cache_keys():
try:
nuevo = loader_for_key(key)
@@ -58,7 +43,6 @@ def cache_refresh_existing(loader_for_key):
def cache_invalidate(prefix: str = None) -> None:
"""Invalida todo el caché, o solo las claves de un prefijo."""
with _LOCK:
if prefix is None:
_CACHE.clear()
@@ -73,13 +57,10 @@ def cache_stats() -> dict:
return {"entradas": len(_CACHE), "claves": list(_CACHE.keys())}
# ── Refresco en segundo plano ──────────────────────────────────────────────
_background_started = False
def start_background_refresh(refresh_fn: Callable[[], None], interval: int = 240):
"""Lanza un hilo que ejecuta refresh_fn cada `interval` segundos (4 min por defecto,
antes de que expire el TTL de 5 min, para mantener el caché siempre caliente)."""
def start_background_refresh(refresh_fn: Callable[[], None], interval: int = 900):
global _background_started
if _background_started:
return