Skip to main content

infigraph_docs/
watch.rs

1use std::path::Path;
2use std::sync::mpsc;
3use std::time::{Duration, Instant};
4
5use anyhow::Result;
6use notify::{Config, RecursiveMode, Watcher};
7
8use crate::{is_document_file, DocIndex};
9
10pub fn watch_docs(
11    root: &Path,
12    debounce_ms: u64,
13    stop_rx: mpsc::Receiver<()>,
14    log_prefix: &str,
15) -> Result<()> {
16    let (tx, rx) = mpsc::channel();
17    let config = Config::default().with_poll_interval(Duration::from_millis(debounce_ms));
18    let mut watcher = notify::RecommendedWatcher::new(tx, config)?;
19    watcher.watch(root, RecursiveMode::Recursive)?;
20
21    let debounce = Duration::from_millis(debounce_ms);
22    let mut last_reindex = Instant::now();
23    let mut pending = false;
24
25    loop {
26        if stop_rx.try_recv().is_ok() {
27            eprintln!("[{log_prefix}] stopped");
28            break;
29        }
30
31        match rx.recv_timeout(Duration::from_millis(500)) {
32            Ok(Ok(event)) => {
33                if event.paths.iter().any(|p| is_document_file(p)) {
34                    pending = true;
35                }
36            }
37            Ok(Err(e)) => eprintln!("[{log_prefix}] watch error: {e}"),
38            Err(mpsc::RecvTimeoutError::Timeout) => {}
39            Err(mpsc::RecvTimeoutError::Disconnected) => break,
40        }
41
42        if pending && last_reindex.elapsed() >= debounce {
43            eprintln!("[{log_prefix}] document change detected, reindexing...");
44            let mut idx = match DocIndex::open(root) {
45                Ok(i) => i,
46                Err(e) => {
47                    eprintln!("[{log_prefix}] open error: {e}");
48                    pending = false;
49                    continue;
50                }
51            };
52            if let Err(e) = idx.init() {
53                eprintln!("[{log_prefix}] init error: {e}");
54            } else {
55                match idx.index() {
56                    Ok(r) => eprintln!(
57                        "[{log_prefix}] reindexed: {} files, {} chunks",
58                        r.indexed_files, r.total_chunks
59                    ),
60                    Err(e) => eprintln!("[{log_prefix}] index error: {e}"),
61                }
62            }
63            pending = false;
64            last_reindex = Instant::now();
65        }
66    }
67
68    Ok(())
69}