Cannot get notify crate to work

Hi - I'm doing something stupid, but I can't get the notify crate to work. In the code below I expect to see at least 10 events, but I'm seeing 0. What am I missing? Thanks!

(This is on macOS, latest rust, latest notify crate (6.x), and the multiple sleeps are grasping at straws to mitigate any asynchronous timing issues...)

use notify::{Config, RecommendedWatcher, RecursiveMode, Watcher};
use std::env::temp_dir;
use std::fs::{create_dir_all, write};
use std::thread;
use std::time::Duration;

#[test]
fn do_it() -> anyhow::Result<()> {
    let root = temp_dir();
    let root = root.parent().unwrap();
    let root = root.join("my_notify_test");
    create_dir_all(&root)?;
    println!("root: {:?}", &root);

    // attach the notifification
    {
        let (tx, rx) = std::sync::mpsc::channel();
        // Automatically select the best implementation for your platform.
        // You can also access each implementation directly e.g. INotifyWatcher.
        let mut watcher = RecommendedWatcher::new(tx, Config::default())?;

        // Add a path to be watched. All files and directories at that path and
        // below will be monitored for changes.
        watcher.watch(root.as_ref(), RecursiveMode::Recursive)?;

        thread::spawn(move || {
            println!("waiting for notifications...");
            for res in rx {
                match res {
                    Ok(event) => println!("Change: {event:?}"),
                    Err(error) => eprintln!("Error: {error:?}"),
                }
            }
        });
    }

    // create some events
    for i in 0..10 {
        let f = root.join(i.to_string());
        println!("writing to {:?}", f);
        write(f, format!("hello {}", i).to_string().into_bytes()).unwrap();
        thread::sleep(Duration::from_millis(100));
    }
    thread::sleep(Duration::from_millis(1000));
    Ok(())
}

leads to:

/Users/coliny/.cargo/bin/cargo test --color=always --lib notify_test::notify_test --no-fail-fast --manifest-path /Users/coliny/Dev/com.qfi.health/src/rust/aaa_sandbox/Cargo.toml -- --format=json -Z unstable-options --show-output
Testing started at 08:43 ...
    Finished test [unoptimized + debuginfo] target(s) in 0.29s
     Running unittests src/lib.rs (target/debug/deps/aaa_sandbox-f658eb46af2c0a68)
root: "/var/folders/5y/d6h0nl814gdcttpccc5ykfm00000gn/pj_notify_test"
waiting for notifications...
writing to "/var/folders/5y/d6h0nl814gdcttpccc5ykfm00000gn/pj_notify_test/0"
writing to "/var/folders/5y/d6h0nl814gdcttpccc5ykfm00000gn/pj_notify_test/1"
writing to "/var/folders/5y/d6h0nl814gdcttpccc5ykfm00000gn/pj_notify_test/2"
writing to "/var/folders/5y/d6h0nl814gdcttpccc5ykfm00000gn/pj_notify_test/3"
writing to "/var/folders/5y/d6h0nl814gdcttpccc5ykfm00000gn/pj_notify_test/4"
writing to "/var/folders/5y/d6h0nl814gdcttpccc5ykfm00000gn/pj_notify_test/5"
writing to "/var/folders/5y/d6h0nl814gdcttpccc5ykfm00000gn/pj_notify_test/6"
writing to "/var/folders/5y/d6h0nl814gdcttpccc5ykfm00000gn/pj_notify_test/7"
writing to "/var/folders/5y/d6h0nl814gdcttpccc5ykfm00000gn/pj_notify_test/8"
writing to "/var/folders/5y/d6h0nl814gdcttpccc5ykfm00000gn/pj_notify_test/9"

Process finished with exit code 0

(playground: Rust Playground)

My awesome colleague (RAV64 · GitHub) aka @MikiS pointed out that moving the blocking loop into the thread allows execution to continue to the end of the scope, which then results in the tx and rx being dropped.

Obvious when you think about it :wink:

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.