refactor: centralize model cache invalidation
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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":
|
||||
|
||||
@@ -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 = (
|
||||
|
||||
@@ -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
@@ -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):
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"})
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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 == {}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user