notify-rs / notify

🔭 Cross-platform filesystem notification library for Rust.
https://docs.rs/notify
2.66k stars 209 forks source link

missing events while watching a file on WSL #254

Open Mimerme opened 4 years ago

Mimerme commented 4 years ago

System details

What you did (as detailed as you can)

let mut water : RecommendedWatcher = Watcher::new_immediate(move |res| tx.send(res).unwrap()).unwrap();

water.configure(Config::PreciseEvents(true)).unwrap();
water.watch(file_watch, RecursiveMode::Recursive).unwrap();

loop {
     match rx.recv() {
        Ok(event) => println!("{:?}", event),
        Err(e) => println!("watch error: {:?}", e),
    }
}

Running this code and setting file_watch to a specific text file and then editing it in vim and saving it only prints the first 3 events, but nothing after that.

What you expected

Editing it in vim and saving it only prints the first 3 events for the first save, but nothing after that. I expected that making additional edits and saving them would print more events, but this did not happen.

What happened

Only the first 3 events when editing with vim are printed.

Additional Notes

When setting file_watch to the text file's directory, the program actually prints that events where the paths attribute contains the specific file when writing multiple times with vim. I think there's an issue in the library with filtering out specific events.

Nejat commented 3 years ago

Hi, I ran across this as well, except while using notify 4.0.15 and I didn't receive any events.

I ran the same application in the following three environments (each environment updated to the latest version):

Windows 10 Pro Workstation WSL 2 PopOS! 20.10 (in hyper-v)

using rust 1.48

Windows and PopOS! the simple application behaves as expected, though with differing raw events and in WSL the application does not receive any notifications.

mx00s commented 3 years ago

I'm seeing behavior in cargo-watch and watchexec which might be explained by this bug and, if it's related, a potential clue.

As expected, modifying a watched file from within the WSL2 terminal, e.g. using echo -e "\n" >> src/lib.rs or editing in the term-based emacs, triggers the specified command. However, modifying the same file from VS Code using remote WSL doesn't trigger the command.

EDIT: For anyone else seeing this behavior, I also discovered running cargo-watch from VS Code's Terminal feature successfully triggers the specified command.

jmquigs commented 3 years ago

I confirmed this issue occurs in WSL2 in windows build Version 10.0.19043.1110. I don't run insider builds, so I don't know if a more recent version of WSL/Win10 fixes it. It worked with WSL 1.

When running in WSL, the windows implementation of notify-rs is not actually used. The inotify watcher is used. The mio poll function is simply not returning, so maybe inotify is not actually producing anything. I guess its an issue with WSL2.

A workaround is to use the PollWatcher, which does work, with a performance hit: PollWatcher::with_delay(Arc::new(Mutex::new(event_fn)), Duration::from_millis(500))

0xpr03 commented 3 years ago

Yeah I also guess it's an issue with how WSL2 works and is not reporting any changes to the linux kernel for the virtualized file system.

0xpr03 commented 2 years ago

From what I see, we can only use something like this to detect a WSL2 environment and then switching to polling based file watching..

We can also only present this workaround inside the upcoming function in #441