feat: add 5-minute TTL cache for PostgreSQL history queries
This commit is contained in:
+17
-1
@@ -5,8 +5,10 @@ FastAPI web interface for water monitoring system
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
import time
|
||||
from contextlib import asynccontextmanager
|
||||
from datetime import datetime, timedelta
|
||||
from threading import Lock
|
||||
from typing import Any, Dict, List
|
||||
|
||||
import requests
|
||||
@@ -34,6 +36,11 @@ from .water_scraper_v3 import EnhancedWaterMonitorScraper
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
# Simple thread-safe TTL cache for PostgreSQL history queries
|
||||
HISTORY_CACHE: Dict[str, tuple] = {}
|
||||
HISTORY_CACHE_LOCK = Lock()
|
||||
HISTORY_TTL = 300 # 5 minutes
|
||||
|
||||
# Dashboard HTML is loaded once at import from src/static/dashboard.html.
|
||||
_DASHBOARD_HTML_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "static", "dashboard.html")
|
||||
try:
|
||||
@@ -448,19 +455,28 @@ async def get_postgres_history(
|
||||
limit: int = Query(2000, ge=1, le=5000),
|
||||
):
|
||||
"""Get historical measurements for a station from PostgreSQL."""
|
||||
cache_key = f"{station_code}:{hours}:{limit}"
|
||||
now = time.monotonic()
|
||||
with HISTORY_CACHE_LOCK:
|
||||
cached = HISTORY_CACHE.get(cache_key)
|
||||
if cached and now - cached[0] < HISTORY_TTL:
|
||||
return cached[1]
|
||||
try:
|
||||
db_config = Config.get_database_config()
|
||||
if db_config["type"] != "postgresql":
|
||||
raise RuntimeError("PostgreSQL is not configured")
|
||||
history = PostgresHistory(db_config["connection_string"])
|
||||
end_time = datetime.now()
|
||||
return await asyncio.to_thread(
|
||||
data = await asyncio.to_thread(
|
||||
history.station_history,
|
||||
station_code,
|
||||
end_time - timedelta(hours=hours),
|
||||
end_time,
|
||||
limit,
|
||||
)
|
||||
with HISTORY_CACHE_LOCK:
|
||||
HISTORY_CACHE[cache_key] = (now, data)
|
||||
return data
|
||||
except RuntimeError as error:
|
||||
raise HTTPException(status_code=503, detail=str(error))
|
||||
except Exception as error:
|
||||
|
||||
Reference in New Issue
Block a user