"""Async-safe TTL-LRU cache.""" from __future__ import annotations import asyncio import hashlib import json import time from collections import OrderedDict from app.config import cfg class TTLCache: """Async-safe LRU cache with per-entry TTL.""" def __init__(self, maxsize: int = 256, ttl: int = 3600): self._cache: OrderedDict = OrderedDict() self._maxsize = maxsize self._ttl = ttl self._lock = asyncio.Lock() def _key(self, *args) -> str: payload = json.dumps(args, ensure_ascii=False, sort_keys=True) return hashlib.sha256(payload.encode()).hexdigest()[:20] async def get(self, *args): async with self._lock: k = self._key(*args) if k in self._cache: value, ts = self._cache[k] if time.monotonic() - ts < self._ttl: self._cache.move_to_end(k) return value del self._cache[k] return None async def set(self, value, *args): async with self._lock: k = self._key(*args) self._cache[k] = (value, time.monotonic()) self._cache.move_to_end(k) if len(self._cache) > self._maxsize: self._cache.popitem(last=False) search_cache = TTLCache(maxsize=cfg.CACHE_SIZE, ttl=cfg.CACHE_TTL) analysis_cache = TTLCache(maxsize=cfg.CACHE_SIZE, ttl=cfg.CACHE_TTL) rewrite_cache = TTLCache(maxsize=cfg.CACHE_SIZE, ttl=cfg.CACHE_TTL * 6)