improve cache eviction logic to handle file access errors and ensure stability

This commit is contained in:
Boody
2026-07-29 12:41:31 +03:00
parent 46905ab9b0
commit 9914651cc9
+38 -20
View File
@@ -98,31 +98,49 @@ class TTSService:
self._enforce_cache_limit() self._enforce_cache_limit()
def _enforce_cache_limit(self): def _enforce_cache_limit(self):
"""Evicts oldest files if the cache exceeds the configured byte limit.""" """Evicts oldest files if the cache exceeds the configured byte limit."""
if self.max_cache_bytes <= 0: if self.max_cache_bytes <= 0:
return return
files = [f for f in self.cache_dir.glob("*.*") if f.is_file()] try:
total_size = sum(f.stat().st_size for f in files) files = []
total_size = 0
if total_size > self.max_cache_bytes: # Safely scan files and sum sizes, ignoring files deleted mid-scan
logger.info(f"TTS cache ({total_size} bytes) exceeded limit ({self.max_cache_bytes} bytes). Evicting oldest files.") for f in self.cache_dir.glob("*.*"):
try:
if f.is_file():
files.append(f)
total_size += f.stat().st_size
except OSError:
continue
# Sort files by modification time (oldest first) if total_size > self.max_cache_bytes:
files.sort(key=lambda f: f.stat().st_mtime) logger.info(
f"TTS cache ({total_size} bytes) exceeded limit ({self.max_cache_bytes} bytes). Evicting oldest files."
)
# Trim down to 80% of max capacity so we aren't constantly triggering this on every new generation # Sort files by modification time (oldest first)
target_size = self.max_cache_bytes * 0.8 try:
files.sort(key=lambda f: f.stat().st_mtime)
except OSError as e:
logger.warning(f"Failed to sort cache files by mtime: {e}")
while files and total_size > target_size: # Trim down to 80% of max capacity
f = files.pop(0) target_size = self.max_cache_bytes * 0.8
try:
size = f.stat().st_size while files and total_size > target_size:
f.unlink() f = files.pop(0)
total_size -= size try:
except FileNotFoundError: size = f.stat().st_size
# File was deleted by another process f.unlink()
continue total_size -= size
except OSError as e:
logger.warning(f"Failed to evict cache file {f}: {e}")
continue
except Exception as e:
logger.warning(f"Error enforcing TTS cache limit: {e}", exc_info=True)
def clear_cache(self): def clear_cache(self):
count = 0 count = 0