notify-rs

What is notify-rs

RecommendedWatcher vs PollWatcher

RecommendedWatcher PollWatcher
What Implementation of Watcher trait provided by the notify crate same
How Watches inodes. Drawback on linux: on every file change, linux creates new inode. Hence we get 2 events write,Remove. Where remove is false positive. Watches Paths(not inodes). This does not generate Remove event on file edit.

Code

RecommendedWatcher


        fn main() {
            let mut rt = tokio::runtime::new().unwrap();
            let local = LocalSet::new();
            local.block_on(&mut rt, async {
                match do_main().await {
                    Ok (_o) => {
                        println!("Success");
                    }
                    Err (e) => {
                        println!("do_main failed");
                    }
                }
            });
        }
        pub async fn do_main() -> Result<(), String> {
            match do_start().await {
                Ok (join_handles) => {
                    for join in join_handles {
                        if let Err(e) = join.await {
                            println!("join failed {}", e);
                        }
                    }
                }
                Err(e) => {
                    return Err(str);
                }
            }
            Ok(())
        }
        pub async fn do_start() -> Result>, ()> {
            loop {
                match Monitor::spawn_task().await {
                    Ok (h) => {
                        join_handles.push(h);
                    }
                    Err (e) => {
                        println!(e);
                        break;
                    }
                }
                break;
            }
        }
        pub struct Monitor{}
        impl Monitor {
            pub async fn spawn_task () -> Result, Box >{
                let handle = tokio::spawn(async {
                    let Err (e) = Self::async_watch(path).await {
                        match e.kind {
                            notify::ErrorKind::Io(_) => {
                                prinlnt!("{} IO Error", e);
                            }
                            _ => {}
                        }
                    }
                });
                Ok(handle)
            }
            async fn async_watcher() -> notify::Result<(RecommendedWatcher, Receiver>)> {
                let (mut tx, rx) = channel(1);
            
                let watcher = RecommendedWatcher::new(
                    move |res| {
                        futures::executor::block_on(async {
                            tx.send(res).await.unwrap();
                        })
                    },
                    Config::default(),
                )?;
                Ok((watcher, rx))
            }
            async fn async_watch>(path: P) -> notify::Result<()> {
                let (mut watcher, mut rx) = async_watcher()?;
            
                watcher.watch(path.as_ref(), RecursiveMode::Recursive)?;
            
                while let Some(res) = rx.next().await {
                    match res {
                        Ok(event) => {
                            println!("changed: {:?}", event);
                            match event.kind {
                                notify::Eventkind::Remove(notify::event::Removekind::File) => {
                                    // Rewatch
                                    watcher.watch (path.as_ref(), RecursiveMode::Recursive)?;
                                },
                                _ => {}
                            }
                        },
                        Err(e) => println!("watch error: {:?}", e),
                    }
                }
                Ok(())
            }
        }
    

PollWatcher


        fn main() {
            let mut rt = tokio::runtime::new().unwrap();
            let local = LocalSet::new();
            local.block_on(&mut rt, async {
                match async_watch(path).await {
                    Ok (_o) => {
                        println!("Success");
                    }
                    Err (e) => {
                        println!("do_main failed");
                    }
                }
            });
        }
        async fn async_watch(path: &str) -> notify::Result<()> {
            enum Message {
                Event(notify::Result),
            }
        
            let (tx, rx):(async_channel::Sender, async_channel::Reciever) = async_channel::unbounded();
            let tx_c = tx.clone();

            let mut watcher = PollWatcher::new(
                move |watch_event| {
                    tx_c.send(Message::Event(watch_event)).unwrap();
                },
                Config::default(),
            )?;
        
            watcher.watch(path.as_ref(), RecursiveMode::Recursive)?;
        
            while let Ok(res) = rx.recv().await {
                match res {
                    Message::Event(e) => println!("Watch event {e:?}"),
                    Message::Scan(e) => println!("Scan event {e:?}"),
                }
            }
        
            Ok(())
        }