Replace in-memory TTL cache with Redis
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user