diff --git a/src/recallforge/watch_folder.py b/src/recallforge/watch_folder.py index 4594065..8cd7414 100644 --- a/src/recallforge/watch_folder.py +++ b/src/recallforge/watch_folder.py @@ -176,13 +176,17 @@ def _build_snapshot(self, config: WatchConfig) -> Dict[str, Tuple[int, int, int] continue return snap - def _scanner_loop(self, watch_id: str) -> None: + def _scanner_loop( + self, + watch_id: str, + initial_snapshot: Optional[Dict[str, Tuple[int, int, int]]] = None, + ) -> None: config = WatchConfig.from_dict(self.watches[watch_id]["config"]) root = Path(config.folder_path).expanduser().resolve() queue = self.queues[watch_id] evt = self.running[watch_id] - prev = self._build_snapshot(config) + prev = dict(initial_snapshot or self._build_snapshot(config)) while evt.is_set(): current = self._build_snapshot(config) @@ -349,8 +353,13 @@ def start_watch(self, config: WatchConfig) -> str: self.queues[watch_id] = Queue() self.running[watch_id] = threading.Event() self.running[watch_id].set() + initial_snapshot = self._build_snapshot(config) - s = threading.Thread(target=self._scanner_loop, args=(watch_id,), daemon=True) + s = threading.Thread( + target=self._scanner_loop, + args=(watch_id, initial_snapshot), + daemon=True, + ) w = threading.Thread(target=self._worker_loop, args=(watch_id,), daemon=True) s.start() w.start() diff --git a/tests/test_watch_folder.py b/tests/test_watch_folder.py index 56fd23a..154cba6 100644 --- a/tests/test_watch_folder.py +++ b/tests/test_watch_folder.py @@ -39,6 +39,15 @@ def embed_image(self, image): return [0.0] * 8 +def _wait_until(predicate, timeout: float = 3.0, interval: float = 0.05) -> bool: + deadline = time.time() + timeout + while time.time() < deadline: + if predicate(): + return True + time.sleep(interval) + return predicate() + + def test_watch_folder_create_and_modify(tmp_path): storage = FakeStorage() backend = FakeBackend() @@ -145,9 +154,9 @@ def test_watch_folder_image_uses_logical_path(tmp_path): image_path = watched / "diagram.png" image_path.write_bytes(b"fake image bytes") - time.sleep(1.0) + assert _wait_until(lambda: bool(storage.image_indexes)) image_path.unlink() - time.sleep(1.0) + assert _wait_until(lambda: ("diagram.png", "default", False) in storage.deletes) daemon.stop_watch(watch_id) @@ -175,9 +184,9 @@ def test_watch_folder_document_uses_logical_path_and_child_cleanup(tmp_path): document_path = watched / "notes.docx" document_path.write_bytes(b"placeholder") - time.sleep(1.0) + assert _wait_until(lambda: bool(storage.document_indexes)) document_path.unlink() - time.sleep(1.0) + assert _wait_until(lambda: ("notes.docx", "default", True) in storage.deletes) daemon.stop_watch(watch_id)