Actualizar docker-compose.yml con sintaxis YAML corregida y puerto 80 para frontend

This commit is contained in:
Administrator
2026-08-29 13:00:33 -05:00
parent 54581c21ab
commit 15c577207d
63 changed files with 11740 additions and 2864 deletions

View File

@@ -1,5 +1,8 @@
# backend/cache_manager.py
"""Caché global en memoria con refresco en segundo plano (igual que el dashboard de ventas)."""
"""
Caché global en memoria con refresco en segundo plano.
Independiente de Streamlit. Mantiene los datos calientes para respuestas instantáneas.
"""
import time
import threading
from typing import Any, Callable, Dict, Tuple
@@ -13,25 +16,37 @@ 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:
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."""
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)
@@ -43,6 +58,7 @@ 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()
@@ -57,10 +73,13 @@ 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 = 900):
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)."""
global _background_started
if _background_started:
return