Description
The file watcher in documents.rs has several resilience gaps that could cause data loss, deadlocks, or resource leaks.
Current State
src-tauri/src/documents.rs:1073+ — watcher thread spins on rx.recv_timeout(Duration::from_secs(2)) indefinitely. If the watched folder is deleted / renamed / unmounted (external drive), notify stops delivering events but the thread keeps looping.
- Next scan via
discover_files on a missing folder returns empty → the chunk index gets wiped.
WatcherState.handle uses std::sync::Mutex; start() calls stop() (which h.join() — blocks the calling thread) while holding the mutex. On the Tauri tokio thread pool this can deadlock.
- No explicit debouncing (though
notify 7 supports it) — rapid file churn (e.g., git operations in the watched folder) fires many events.
Suggested Fix
Verification
Automation Hints
scope: src-tauri/src/documents.rs
do-not-touch: FTS schema, chunking logic
approach: refactor-to-config
risk: medium (async refactor)
max-files-changed: 2
blocked-by: none
bail-if: notify 7 lacks sufficient debouncing primitives without a second crate
Priority
Medium — avoids data-loss edge cases for document-heavy users.
Description
The file watcher in
documents.rshas several resilience gaps that could cause data loss, deadlocks, or resource leaks.Current State
src-tauri/src/documents.rs:1073+— watcher thread spins onrx.recv_timeout(Duration::from_secs(2))indefinitely. If the watched folder is deleted / renamed / unmounted (external drive),notifystops delivering events but the thread keeps looping.discover_fileson a missing folder returns empty → the chunk index gets wiped.WatcherState.handleusesstd::sync::Mutex;start()callsstop()(whichh.join()— blocks the calling thread) while holding the mutex. On the Tauri tokio thread pool this can deadlock.notify7 supports it) — rapid file churn (e.g., git operations in the watched folder) fires many events.Suggested Fix
notify::EventKind::Removetargeting the watched root path, callstop()on self, emit adocuments-folder-missingTauri event so the UI can prompt user to reselect.Path::exists(&folder_path)check; skip rescan if false to prevent index wipe.std::sync::Mutex+std::thread::JoinHandlewithtokio::sync::Mutex+tokio::task::JoinHandle; makestop()async.notify-debouncer-full0.3 or a manual 500ms collector) to coalesce rapid events.Verification
cargo test documentspassesfor i in {1..100}; do touch file$i; done) → watcher processes one coalesced event, not 100.Automation Hints
scope: src-tauri/src/documents.rs
do-not-touch: FTS schema, chunking logic
approach: refactor-to-config
risk: medium (async refactor)
max-files-changed: 2
blocked-by: none
bail-if: notify 7 lacks sufficient debouncing primitives without a second crate
Priority
Medium — avoids data-loss edge cases for document-heavy users.