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,10 +1,11 @@
import asyncio
import json
import logging
import os
import re
import shutil
from services.cache import smart_cache
from services.cache import cache_get, cache_set
logger = logging.getLogger(__name__)
@@ -17,6 +18,8 @@ ATTR_PENDING = 197
ATTR_UNCORRECTABLE = 198
ATTR_WEAR_LEVELING = 177 # SSD wear leveling
SMART_CACHE_TTL = int(os.environ.get("SMART_CACHE_TTL", "120"))
def smartctl_available() -> bool:
return shutil.which("smartctl") is not None
@@ -26,19 +29,22 @@ def sg_ses_available() -> bool:
return shutil.which("sg_ses") is not None
async def get_smart_data(device: str) -> dict:
"""Run smartctl -a -j against a device, with caching."""
async def get_smart_data(device: str) -> tuple[dict, bool]:
"""Run smartctl -a -j against a device, with caching.
Returns (data, cache_hit) tuple.
"""
# Sanitize device name: only allow alphanumeric and hyphens
if not re.match(r"^[a-zA-Z0-9\-]+$", device):
raise ValueError(f"Invalid device name: {device}")
cached = smart_cache.get(device)
cached = await cache_get(f"jbod:smart:{device}")
if cached is not None:
return cached
return (cached, True)
result = await _run_smartctl(device)
smart_cache.set(device, result)
return result
await cache_set(f"jbod:smart:{device}", result, SMART_CACHE_TTL)
return (result, False)
async def _run_smartctl(device: str) -> dict: