From 971604d14f653e82b955da19a1d08a1287875d08 Mon Sep 17 00:00:00 2001 From: Jamie Pine Date: Fri, 30 Jan 2026 16:50:24 -0800 Subject: [PATCH] Implement profile cache management in audio processing - Added `clear_profile_cache` function to manage cache files for specific profiles. - Integrated cache clearing in `add_profile_sample`, `delete_profile`, and `delete_profile_sample` functions to ensure stale audio caches are invalidated after modifications. - Enhanced `clear_voice_prompt_cache` to also delete combined audio files, improving overall cache management. --- backend/profiles.py | 23 ++++++++++++++++++++++- backend/utils/cache.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/backend/profiles.py b/backend/profiles.py index 42f2144b..cda6bee0 100644 --- a/backend/profiles.py +++ b/backend/profiles.py @@ -22,7 +22,7 @@ from .database import ( ) from .utils.audio import validate_reference_audio, load_audio, save_audio from .utils.images import validate_image, process_avatar -from .utils.cache import _get_cache_dir +from .utils.cache import _get_cache_dir, clear_profile_cache from .tts import get_tts_model from . import config @@ -121,6 +121,10 @@ async def add_profile_sample( db.commit() db.refresh(db_sample) + # Invalidate combined audio cache for this profile + # Since a new sample was added, any cached combined audio is now stale + clear_profile_cache(profile_id) + return ProfileSampleResponse.model_validate(db_sample) @@ -242,6 +246,9 @@ async def delete_profile( if profile_dir.exists(): shutil.rmtree(profile_dir) + # Clean up combined audio cache files for this profile + clear_profile_cache(profile_id) + return True @@ -263,6 +270,9 @@ async def delete_profile_sample( if not sample: return False + # Store profile_id before deleting + profile_id = sample.profile_id + # Delete audio file audio_path = Path(sample.audio_path) if audio_path.exists(): @@ -272,6 +282,10 @@ async def delete_profile_sample( db.delete(sample) db.commit() + # Invalidate combined audio cache for this profile + # Since the sample set changed, any cached combined audio is now stale + clear_profile_cache(profile_id) + return True @@ -295,10 +309,17 @@ async def update_profile_sample( if not sample: return None + # Store profile_id before updating + profile_id = sample.profile_id + sample.reference_text = reference_text db.commit() db.refresh(sample) + # Invalidate combined audio cache for this profile + # Since the reference text changed, cache keys and combined text are now stale + clear_profile_cache(profile_id) + return ProfileSampleResponse.model_validate(sample) diff --git a/backend/utils/cache.py b/backend/utils/cache.py index fddc7b16..1c420ba0 100644 --- a/backend/utils/cache.py +++ b/backend/utils/cache.py @@ -105,11 +105,46 @@ def clear_voice_prompt_cache() -> int: deleted_count = 0 if cache_dir.exists(): + # Delete prompt cache files for cache_file in cache_dir.glob("*.prompt"): try: cache_file.unlink() deleted_count += 1 except Exception as e: print(f"Failed to delete cache file {cache_file}: {e}") + + # Delete combined audio files + for audio_file in cache_dir.glob("combined_*.wav"): + try: + audio_file.unlink() + deleted_count += 1 + except Exception as e: + print(f"Failed to delete combined audio file {audio_file}: {e}") + + return deleted_count + + +def clear_profile_cache(profile_id: str) -> int: + """ + Clear cache files for a specific profile. + + Args: + profile_id: Profile ID + + Returns: + Number of cache files deleted + """ + cache_dir = _get_cache_dir() + deleted_count = 0 + + if cache_dir.exists(): + # Delete combined audio files for this profile + pattern = f"combined_{profile_id}_*.wav" + for audio_file in cache_dir.glob(pattern): + try: + audio_file.unlink() + deleted_count += 1 + except Exception as e: + print(f"Failed to delete combined audio file {audio_file}: {e}") return deleted_count