refactor: centralize model cache invalidation

This commit is contained in:
Dariusz L
2026-08-08 19:03:16 +02:00
parent 5fa1e76902
commit cfeb333546
9 changed files with 39 additions and 27 deletions
+2 -6
View File
@@ -30,10 +30,7 @@ from ..path_utils import (
is_path_within,
write_json_atomic,
)
from ..resolver import (
invalidate_local_hash_match_cache,
)
from ..scanner import invalidate_model_files_cache
from ..resolver import invalidate_model_caches
from ..settings import (
load_settings,
normalize_download_backend,
@@ -144,8 +141,7 @@ context.get_path_identity = get_path_identity
context.is_path_within = is_path_within
context.write_json_atomic = write_json_atomic
context.get_category_folder_keys = get_category_folder_keys
context.invalidate_model_files_cache = invalidate_model_files_cache
context.invalidate_local_hash_match_cache = invalidate_local_hash_match_cache
context.invalidate_model_caches = invalidate_model_caches
context._extract_expected_sha256 = metadata._extract_expected_sha256
context.normalize_metadata_file_path = metadata.normalize_metadata_file_path
+1 -2
View File
@@ -967,8 +967,7 @@ def download_file_with_aria2(
f"Size: {facade.format_bytes(size)}, Time: {elapsed:.1f}s, "
f"Avg speed: {facade.format_bytes(int(avg_speed))}/s"
)
facade.invalidate_model_files_cache()
facade.invalidate_local_hash_match_cache()
facade.invalidate_model_caches()
return result
if state == "error":
+1 -2
View File
@@ -487,8 +487,7 @@ def download_huggingface_xet(
f"Size: {facade.format_bytes(size)}, Time: {elapsed:.1f}s, "
f"Avg speed: {facade.format_bytes(int(avg_speed))}/s"
)
facade.invalidate_model_files_cache()
facade.invalidate_local_hash_match_cache()
facade.invalidate_model_caches()
return result
except Exception as exc:
was_cancelled = (
+1 -2
View File
@@ -296,8 +296,7 @@ def download_file(
f"Size: {facade.format_bytes(downloaded)}, Time: {elapsed:.1f}s, "
f"Avg speed: {facade.format_bytes(int(avg_speed))}/s"
)
facade.invalidate_model_files_cache()
facade.invalidate_local_hash_match_cache()
facade.invalidate_model_caches()
except requests.exceptions.RequestException as exc:
error_msg = facade._sanitize_download_error(exc)
+7 -1
View File
@@ -22,7 +22,7 @@ log = create_module_logger(__name__)
from .local_hash_matches import collect_local_hash_matches_for_result
from .matcher import find_matches, strip_known_model_extension
from .scanner import get_model_files
from .scanner import get_model_files, invalidate_model_files_cache
from .type_utils import MODEL_EXTENSIONS as _MODEL_EXTENSIONS
from .type_utils import (
as_dict,
@@ -74,6 +74,12 @@ def invalidate_local_hash_match_cache() -> None:
_LOCAL_HASH_MATCH_CACHE = None
def invalidate_model_caches() -> None:
"""Clear all in-memory caches that depend on the local model inventory."""
invalidate_model_files_cache()
invalidate_local_hash_match_cache()
def _clone_hash_match(match: Dict[str, Any]) -> Dict[str, Any]:
cloned = dict(match)
if isinstance(cloned.get("model"), dict):
+6 -1
View File
@@ -87,10 +87,15 @@ def register_routes(self):
apply_resolution,
get_local_model_hash_metadata,
invalidate_local_hash_match_cache,
invalidate_model_caches,
search_local_matches,
search_local_matches_by_hash,
)
from ..scanner import find_local_file_path, get_model_files, invalidate_model_files_cache
from ..scanner import (
find_local_file_path,
get_model_files,
invalidate_model_files_cache,
)
from ..services.model_service import ModelService
from ..settings import (
TEMPLATE_KEY_ALIASES,
+2 -8
View File
@@ -26,12 +26,7 @@ class SearchSupportService:
self.get_model_list_update_status = context.require(
"get_model_list_update_status"
)
self.invalidate_local_hash_match_cache = context.require(
"invalidate_local_hash_match_cache"
)
self.invalidate_model_files_cache = context.require(
"invalidate_model_files_cache"
)
self.invalidate_model_caches = context.require("invalidate_model_caches")
self.refresh_known_author_fallback_indexes = context.require(
"refresh_known_author_fallback_indexes"
)
@@ -48,8 +43,7 @@ class SearchSupportService:
self.clear_all_search_caches()
self.reload_popular_databases()
self.reload_model_list()
self.invalidate_model_files_cache()
self.invalidate_local_hash_match_cache()
self.invalidate_model_caches()
self.extension.search_result_timestamps.clear()
self.extension.logger.info("Cleared backend search caches")
return self.web.json_response({"success": True, "cleared": "all"})
+17 -1
View File
@@ -3,7 +3,7 @@ import os
import sys
import unittest
from pathlib import Path
from unittest.mock import MagicMock, patch
from unittest.mock import MagicMock, call, patch
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if parent_dir not in sys.path:
@@ -26,6 +26,22 @@ class TestRefactoringUnification(unittest.TestCase):
def test_thresholds(self):
self.assertEqual(MODEL_TITLE_MATCH_THRESHOLD, 82.0)
def test_invalidate_model_caches_clears_inventory_then_hash_matches(self):
from core import resolver
calls = MagicMock()
with patch.object(resolver, "invalidate_model_files_cache") as invalidate_inventory:
with patch.object(
resolver, "invalidate_local_hash_match_cache"
) as invalidate_hash_matches:
calls.attach_mock(invalidate_inventory, "inventory")
calls.attach_mock(invalidate_hash_matches, "hash_matches")
resolver.invalidate_model_caches()
calls.assert_has_calls([call.inventory(), call.hash_matches()])
invalidate_inventory.assert_called_once_with()
invalidate_hash_matches.assert_called_once_with()
def test_normalize_lora_manager_type(self):
self.assertEqual(normalize_lora_manager_type("loras"), "lora")
self.assertEqual(normalize_lora_manager_type("checkpoints"), "checkpoint")
+2 -4
View File
@@ -72,8 +72,7 @@ def _build_routes(overrides=None):
"get_model_list_update_status": MagicMock(
return_value={"loaded": True}
),
"invalidate_local_hash_match_cache": MagicMock(),
"invalidate_model_files_cache": MagicMock(),
"invalidate_model_caches": MagicMock(),
"json_api_endpoint": _json_api_endpoint,
"refresh_known_author_fallback_indexes": MagicMock(
return_value={"refreshed": True}
@@ -106,8 +105,7 @@ async def test_clear_search_cache_route_clears_all_state():
values["clear_all_search_caches"].assert_called_once_with()
values["reload_popular_databases"].assert_called_once_with()
values["reload_model_list"].assert_called_once_with()
values["invalidate_model_files_cache"].assert_called_once_with()
values["invalidate_local_hash_match_cache"].assert_called_once_with()
values["invalidate_model_caches"].assert_called_once_with()
assert values["self"].search_result_timestamps == {}