Replace in-memory TTL cache with Redis

This commit is contained in:
2026-03-07 18:45:15 +00:00
parent 0112875894
commit b11c1bdf98
10 changed files with 238 additions and 54 deletions

View File

@@ -1,4 +1,4 @@
from fastapi import APIRouter, HTTPException
from fastapi import APIRouter, HTTPException, Response
from models.schemas import DriveDetail
from services.smart import get_smart_data
@@ -8,10 +8,10 @@ router = APIRouter(prefix="/api/drives", tags=["drives"])
@router.get("/{device}", response_model=DriveDetail)
async def get_drive_detail(device: str):
async def get_drive_detail(device: str, response: Response):
"""Get SMART detail for a specific block device."""
try:
data = await get_smart_data(device)
data, cache_hit = await get_smart_data(device)
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
@@ -25,4 +25,6 @@ async def get_drive_detail(device: str):
data["zfs_vdev"] = zfs_info["vdev"]
data["zfs_state"] = zfs_info.get("state")
response.headers["X-Cache"] = "HIT" if cache_hit else "MISS"
return DriveDetail(**data)

View File

@@ -1,7 +1,7 @@
import asyncio
import logging
from fastapi import APIRouter
from fastapi import APIRouter, Response
from models.schemas import (
DriveHealthSummary,
@@ -22,7 +22,7 @@ router = APIRouter(prefix="/api/overview", tags=["overview"])
@router.get("", response_model=Overview)
async def get_overview():
async def get_overview(response: Response):
"""Aggregate view of all enclosures, slots, and drive health."""
enclosures_raw = discover_enclosures()
pool_map = await get_zfs_pool_map()
@@ -53,12 +53,19 @@ async def get_overview():
smart_results = await asyncio.gather(*smart_tasks, return_exceptions=True)
smart_map: dict[str, dict] = {}
all_cache_hits = True
any_lookups = False
for (slot_info, dev), result in zip(populated, smart_results):
if isinstance(result, Exception):
logger.warning("SMART query failed for %s: %s", dev, result)
smart_map[dev] = {"device": dev, "smart_supported": False}
all_cache_hits = False
else:
smart_map[dev] = result
data, hit = result
smart_map[dev] = data
any_lookups = True
if not hit:
all_cache_hits = False
slots_out: list[SlotWithDrive] = []
for s in slots_raw:
@@ -170,6 +177,8 @@ async def get_overview():
warnings += 1
host_drives_out.append(HostDrive(**hd))
response.headers["X-Cache"] = "HIT" if (any_lookups and all_cache_hits) else "MISS"
return Overview(
healthy=all_healthy and errors == 0,
drive_count=total_drives,