from __future__ import annotations import logging import time from collections import OrderedDict logger = logging.getLogger(__name__) DEFAULT_TTL_SECONDS = 120 class FileCacheEntry: __slots__ = ("file_key", "file_path", "file_name", "cached_at") def __init__(self, file_key: str, file_path: str = "", file_name: str = ""): self.file_key = file_key self.file_path = file_path self.file_name = file_name self.cached_at = time.monotonic() class FileCache: def __init__(self, ttl_seconds: int = DEFAULT_TTL_SECONDS): self._ttl = ttl_seconds self._entries: OrderedDict[str, FileCacheEntry] = OrderedDict() def add(self, session_key: str, file_key: str, file_path: str = "", file_name: str = "") -> None: self._evict_expired() self._entries[session_key] = FileCacheEntry(file_key, file_path, file_name) def get(self, session_key: str) -> FileCacheEntry | None: self._evict_expired() entry = self._entries.get(session_key) if entry is not None: return entry return None def clear(self, session_key: str) -> None: self._entries.pop(session_key, None) def _evict_expired(self) -> None: now = time.monotonic() expired = [k for k, v in self._entries.items() if now - v.cached_at > self._ttl] for k in expired: self._entries.pop(k, None) _cache_instance: FileCache | None = None def get_file_cache() -> FileCache: global _cache_instance if _cache_instance is None: _cache_instance = FileCache() return _cache_instance