From 7f747f0e681deff9546072525bc5a910d3b60292 Mon Sep 17 00:00:00 2001 From: abhay-codes07 Date: Sun, 12 Jul 2026 14:52:49 +0530 Subject: [PATCH] Fix model file list cache never being reused cache_model_file_list_ compared os.path.getmtime(folder) (a float) against model_file_list_cache[1] (the dirs dict), which is always unequal, so the check returned None on every call and the model tree was re-walked on each /experiment/models request. The top-level folder was also never recorded in dirs, so drop the broken scalar comparison and instead seed the folder's own mtime into dirs (matching folder_paths.recursive_search) so it is validated by the existing per-directory loop and direct additions still invalidate the cache. --- app/model_manager.py | 7 +++-- tests-unit/app_test/model_file_cache_test.py | 29 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 tests-unit/app_test/model_file_cache_test.py diff --git a/app/model_manager.py b/app/model_manager.py index 5928781ca..6445d2263 100644 --- a/app/model_manager.py +++ b/app/model_manager.py @@ -125,8 +125,6 @@ class ModelFileManager: return None if not os.path.isdir(folder): return None - if os.path.getmtime(folder) != model_file_list_cache[1]: - return None for x in model_file_list_cache[1]: time_modified = model_file_list_cache[1][x] folder = x @@ -146,6 +144,11 @@ class ModelFileManager: result: list[str] = [] dirs: dict[str, float] = {} + try: + dirs[directory] = os.path.getmtime(directory) + except FileNotFoundError: + logging.warning(f"Warning: Unable to access {directory}. Skipping this path.") + for dirpath, subdirs, filenames in os.walk(directory, followlinks=True, topdown=True): subdirs[:] = [d for d in subdirs if d not in excluded_dir_names] if not include_hidden_files: diff --git a/tests-unit/app_test/model_file_cache_test.py b/tests-unit/app_test/model_file_cache_test.py new file mode 100644 index 000000000..1cd0e4b37 --- /dev/null +++ b/tests-unit/app_test/model_file_cache_test.py @@ -0,0 +1,29 @@ +import os + +from app.model_manager import ModelFileManager + + +class TestModelFileListCache: + def test_cache_is_reused_when_unchanged(self, tmp_path): + sub = tmp_path / "sub" + sub.mkdir() + (sub / "m.safetensors").write_bytes(b"x") + + mgr = ModelFileManager() + out = mgr.recursive_search_models_(str(tmp_path), 0) + mgr.set_cache(str(tmp_path), out) + + # nothing changed, so the cached result must be returned instead of None + assert mgr.cache_model_file_list_(str(tmp_path)) is out + + def test_cache_invalidated_when_top_folder_changes(self, tmp_path): + mgr = ModelFileManager() + out = mgr.recursive_search_models_(str(tmp_path), 0) + mgr.set_cache(str(tmp_path), out) + assert mgr.cache_model_file_list_(str(tmp_path)) is out + + # a file added directly under the top folder changes its mtime, which must + # invalidate the cache (the top folder is tracked, not just subfolders) + bumped = os.path.getmtime(str(tmp_path)) + 100 + os.utime(str(tmp_path), (bumped, bumped)) + assert mgr.cache_model_file_list_(str(tmp_path)) is None