mirror of
https://github.com/linyqh/NarratoAI.git
synced 2026-08-01 10:55:54 +00:00
Merge pull request #265 from leoz9/codex/add-clear-cache-button
Add system cache clearing action
This commit is contained in:
commit
0733bb9528
@ -4,8 +4,54 @@ import shutil
|
|||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
from app.config import config
|
from app.config import config
|
||||||
|
from app.services.llm.unified_service import UnifiedLLMService
|
||||||
from app.utils import ffmpeg_detector, ffmpeg_utils
|
from app.utils import ffmpeg_detector, ffmpeg_utils
|
||||||
from app.utils.utils import storage_dir
|
from app.utils.utils import clear_keyframes_cache, storage_dir
|
||||||
|
|
||||||
|
|
||||||
|
APPLICATION_CACHE_SESSION_KEYS = (
|
||||||
|
"fonts_cache",
|
||||||
|
"video_files_cache",
|
||||||
|
"songs_cache",
|
||||||
|
"ffmpeg_engine_report",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _clear_streamlit_caches():
|
||||||
|
st.cache_data.clear()
|
||||||
|
cache_resource = getattr(st, "cache_resource", None)
|
||||||
|
if cache_resource is not None:
|
||||||
|
cache_resource.clear()
|
||||||
|
|
||||||
|
|
||||||
|
def clear_application_cache(
|
||||||
|
session_state=None,
|
||||||
|
clear_streamlit_cache=None,
|
||||||
|
clear_llm_cache=None,
|
||||||
|
clear_keyframes_cache=None,
|
||||||
|
reset_ffmpeg_detection=None,
|
||||||
|
):
|
||||||
|
"""Clear runtime caches that can keep stale UI/model/media state."""
|
||||||
|
state = st.session_state if session_state is None else session_state
|
||||||
|
for key in APPLICATION_CACHE_SESSION_KEYS:
|
||||||
|
state.pop(key, None)
|
||||||
|
|
||||||
|
operations = (
|
||||||
|
("streamlit", clear_streamlit_cache or _clear_streamlit_caches),
|
||||||
|
("llm", clear_llm_cache or UnifiedLLMService.clear_cache),
|
||||||
|
("keyframes", clear_keyframes_cache or globals()["clear_keyframes_cache"]),
|
||||||
|
("ffmpeg", reset_ffmpeg_detection or ffmpeg_utils.reset_hwaccel_detection),
|
||||||
|
)
|
||||||
|
|
||||||
|
errors = []
|
||||||
|
for name, operation in operations:
|
||||||
|
try:
|
||||||
|
operation()
|
||||||
|
except Exception as exc:
|
||||||
|
errors.append(f"{name}: {exc}")
|
||||||
|
logger.error(f"Failed to clear {name} cache: {exc}")
|
||||||
|
|
||||||
|
return errors
|
||||||
|
|
||||||
|
|
||||||
def clear_directory(dir_path, tr):
|
def clear_directory(dir_path, tr):
|
||||||
@ -188,7 +234,7 @@ def render_ffmpeg_engine_settings(tr):
|
|||||||
def render_system_panel(tr):
|
def render_system_panel(tr):
|
||||||
"""渲染系统设置面板"""
|
"""渲染系统设置面板"""
|
||||||
with st.expander(tr("System settings"), expanded=False):
|
with st.expander(tr("System settings"), expanded=False):
|
||||||
col1, col2, col3 = st.columns(3)
|
col1, col2, col3, col4 = st.columns(4)
|
||||||
|
|
||||||
with col1:
|
with col1:
|
||||||
if st.button(tr("Clear frames"), use_container_width=True):
|
if st.button(tr("Clear frames"), use_container_width=True):
|
||||||
@ -202,4 +248,12 @@ def render_system_panel(tr):
|
|||||||
if st.button(tr("Clear tasks"), use_container_width=True):
|
if st.button(tr("Clear tasks"), use_container_width=True):
|
||||||
clear_directory(os.path.join(storage_dir(), "tasks"), tr)
|
clear_directory(os.path.join(storage_dir(), "tasks"), tr)
|
||||||
|
|
||||||
|
with col4:
|
||||||
|
if st.button(tr("Clear Cache"), use_container_width=True):
|
||||||
|
errors = clear_application_cache()
|
||||||
|
if errors:
|
||||||
|
st.error(f"{tr('Failed to clear cache')}: {'; '.join(errors)}")
|
||||||
|
else:
|
||||||
|
st.success(tr("Cache cleared"))
|
||||||
|
|
||||||
render_ffmpeg_engine_settings(tr)
|
render_ffmpeg_engine_settings(tr)
|
||||||
|
|||||||
46
webui/components/test_system_settings_unittest.py
Normal file
46
webui/components/test_system_settings_unittest.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import unittest
|
||||||
|
|
||||||
|
from webui.components.system_settings import clear_application_cache
|
||||||
|
|
||||||
|
|
||||||
|
class SystemSettingsCacheTests(unittest.TestCase):
|
||||||
|
def test_clear_application_cache_clears_runtime_caches(self):
|
||||||
|
session_state = {
|
||||||
|
"fonts_cache": ["SimHei"],
|
||||||
|
"video_files_cache": ["a.mp4"],
|
||||||
|
"songs_cache": ["bgm.mp3"],
|
||||||
|
"ffmpeg_engine_report": {"ffmpeg_available": True},
|
||||||
|
"unrelated": "keep",
|
||||||
|
}
|
||||||
|
calls = []
|
||||||
|
|
||||||
|
errors = clear_application_cache(
|
||||||
|
session_state=session_state,
|
||||||
|
clear_streamlit_cache=lambda: calls.append("streamlit"),
|
||||||
|
clear_llm_cache=lambda: calls.append("llm"),
|
||||||
|
clear_keyframes_cache=lambda: calls.append("keyframes"),
|
||||||
|
reset_ffmpeg_detection=lambda: calls.append("ffmpeg"),
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual([], errors)
|
||||||
|
self.assertEqual(["streamlit", "llm", "keyframes", "ffmpeg"], calls)
|
||||||
|
self.assertEqual({"unrelated": "keep"}, session_state)
|
||||||
|
|
||||||
|
def test_clear_application_cache_reports_clear_failures(self):
|
||||||
|
def fail():
|
||||||
|
raise RuntimeError("boom")
|
||||||
|
|
||||||
|
errors = clear_application_cache(
|
||||||
|
session_state={},
|
||||||
|
clear_streamlit_cache=fail,
|
||||||
|
clear_llm_cache=lambda: None,
|
||||||
|
clear_keyframes_cache=lambda: None,
|
||||||
|
reset_ffmpeg_detection=lambda: None,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(1, len(errors))
|
||||||
|
self.assertIn("boom", errors[0])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Loading…
x
Reference in New Issue
Block a user