diff --git a/py/api/__init__.py b/py/api/__init__.py index dfb46b9..68c2ce5 100644 --- a/py/api/__init__.py +++ b/py/api/__init__.py @@ -353,12 +353,18 @@ class PromptManagerAPI( """Invalidate the cached gallery file listing. Called by the image monitor when new files are detected. The workspace - values derived from a scan are dropped with it. + keeps its per-file values, so the next request rebuilds only new or + changed files (see ImageRoutesMixin._workspace_listed); its sort orders + are dropped, as the rescan replaces them anyway. """ self._gallery_cache = {} - self._workspace_listed_cache = {} self._workspace_order_cache = {} + def reset_gallery_roots_cache(self): + """Drop every cached listing and derived workspace value (roots changed).""" + self.invalidate_gallery_cache() + self._workspace_listed_cache = {} + def add_routes(self, routes): """Register all API routes with the ComfyUI server. diff --git a/py/api/admin.py b/py/api/admin.py index 0ef2d4a..4360e00 100644 --- a/py/api/admin.py +++ b/py/api/admin.py @@ -897,7 +897,7 @@ class AdminRoutesMixin: return False GalleryConfig.MONITORING_DIRECTORIES = roots self._cached_output_dir = None - self.invalidate_gallery_cache() + self.reset_gallery_roots_cache() return True def _persist_settings(self): diff --git a/py/api/images.py b/py/api/images.py index 23fa252..5d70ce0 100644 --- a/py/api/images.py +++ b/py/api/images.py @@ -990,7 +990,7 @@ class ImageRoutesMixin: The gallery cache hands out the same list object until it rescans. A rescan reuses the value of every unchanged ``(path, mtime)`` and, when nothing changed, the previous list itself, so the cached sort - orders stay valid. invalidate_gallery_cache drops these values. + orders stay valid. Only a gallery-roots change drops these values. """ key = (index, str(root)) cached = self._workspace_listed_cache.get(key) diff --git a/tests/test_api_workspace_images.py b/tests/test_api_workspace_images.py index 78efb9a..f67fd49 100644 --- a/tests/test_api_workspace_images.py +++ b/tests/test_api_workspace_images.py @@ -1200,14 +1200,18 @@ class TestWorkspaceImages(ImageAPITestCase): self.assertEqual(built, [added[0]]) self.assertEqual(data["total"], len(listed)) self.assertEqual(data["images"][0]["filename"], "new.png") - # Invalidation (the monitor saw new files) and a roots change drop - # every derived value. + # The monitor invalidates the gallery when it sees a new file: the + # next request rebuilds only that file's values, and search finds it. self.api.invalidate_gallery_cache() - self.assertEqual(self.api._workspace_listed_cache, {}) - self.assertEqual(self.api._workspace_order_cache, {}) + self.assertNotEqual(self.api._workspace_listed_cache, {}) + monitored = (self.output_dir / "day-01" / "monitored.png", 9_999_999.5) + scans.append([monitored, *scans[-1]]) built.clear() - response, data = await self.get(limit=10) - self.assertEqual(len(built), len(listed)) + response, data = await self.get(limit=10, q="monitored") + self.assertEqual(response.status, 200) + self.assertEqual(built, [monitored[0]]) + self.assertEqual(self._names(data), ["monitored.png"]) + # A roots change drops every derived value. with patch("py.config.GalleryConfig.MONITORING_DIRECTORIES", []): self.assertTrue(self.api._apply_gallery_roots([str(self.output_dir)])) self.assertEqual(self.api._workspace_listed_cache, {})