-
Notifications
You must be signed in to change notification settings - Fork 225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Notify does not handle the new IsFile
event on macOS.
#465
Comments
IsFile
event on macOs.IsFile
event on macOS.
So from what I've read across all 4 issues, the COW operation emits an Event for the source with a flag |
@0xpr03 thanks for the reply. Yes, the target also receives the event "sometimes". However, I have not debugged deeply enough to be able define what "sometimes" means here. I believe that you should ignore this event, yes. Regarding whether I'm using queue or fsevents, TBH, I have no idea. Googling told me only that these two systems are available on macOS, but I didn't find a way to check which one is being used under the hood. If you want me to provide any logs / run some command/scripts, I'd be happy to. Does it answer your question? |
It has to be kqueue, based on watchexec/cargo-watch. (*) For example rebuilding everything once stuff changes with a debouncer, so they don't care about specific events, but at least one has to be emitted. |
@0xpr03 instead of ignoring this event we can as well just handle it and libraries using notify can pattern match on it and ignore it by themselves. I believe this is a way more generic and safe approach. What do you think about it? |
@0xpr03 Hi :) Do you think that something could be done regarding this issue? Because of it, |
I'm open for PRs. I don't own any macos hardware, so I can't develop this. |
I've been trying to debug this and have not been able to make reasonable progress. From the best as I can tell, there are events that can happen to a cloned file (created with
I don't think it would be correct to ignore events with Here is a demo program. It has an "input" directory, and it copies files from there to an "output" directory whenever the input changes. Running this essentially loops an infinite number of times, since calling use std::error::Error;
use std::path::Path;
use std::sync::mpsc::channel;
use std::time::Duration;
fn main() -> Result<(), Box<dyn Error>> {
if Path::new("output").exists() {
std::fs::remove_dir_all("output")?;
}
if Path::new("input").exists() {
std::fs::remove_dir_all("input")?;
}
std::fs::create_dir("output")?;
std::fs::create_dir("input")?;
std::fs::write("input/abc", "test")?;
std::thread::spawn(|| watch(Path::new("input"), true).unwrap());
// std::thread::spawn(|| watch(Path::new("output"), false).unwrap());
std::thread::sleep(Duration::from_secs(1));
eprintln!("modfying file");
std::fs::write("input/abc", "test 2")?;
std::thread::park();
Ok(())
}
fn watch(path: &Path, do_copy: bool) -> Result<(), Box<dyn Error>> {
use notify::RecursiveMode::*;
let (tx, rx) = channel();
let mut debouncer = notify_debouncer_mini::new_debouncer(Duration::from_secs(1), None, tx)?;
let watcher = debouncer.watcher();
watcher.watch(path, Recursive)?;
println!("Listening for changes... {path:?}");
loop {
match rx.recv().unwrap() {
Ok(event) => {
eprintln!("got event {event:?}",);
if do_copy {
// This simulates what happens when rebuilding the output.
// Remove these two lines to prevent an infinite loop.
// However, it will still loop twice (once for the modification, and once for the copy).
std::fs::remove_dir_all("output")?;
std::fs::create_dir("output")?;
for entry in std::fs::read_dir(path)? {
let entry = entry?;
eprintln!("copy {:?}", entry.path());
std::fs::copy(
entry.path(),
Path::new("output").join(entry.path().file_name().unwrap()),
)?;
}
}
}
Err(e) => {
eprintln!("failed {e:?}");
}
}
}
} |
BREAKING CHANGES Relying on FS events was not reliable across all platforms, and some events are outright ignored based on how the file changes (e.g some IDE do not truly "write" to files directly). See notify-rs/notify#465 and notify-rs/notify#468. We now use a dumb poll system that computes changes every 250ms. The EntryChange struct was thus improved to provide trigger cause, and this is what the watch callback will now send. Additional changes: - Update rust napirs packages and set napi cli to 2.14.8 to avoid duplicate generated content - Adapt tests to the new watching system - Update README
BREAKING CHANGES Relying on FS events was not reliable across all platforms, and some events are outright ignored based on how the file changes (e.g some IDE do not truly "write" to files directly). See notify-rs/notify#465 and notify-rs/notify#468. We now use a dumb poll system that computes changes every 250ms. The EntryChange struct was thus improved to provide trigger cause, and this is what the watch callback will now send. Additional changes: - Update rust napirs packages and set napi cli to 2.14.8 to avoid duplicate generated content - Adapt tests to the new watching system - Update README
System details
rustc --version
: rustc 1.67.0-nightly (b7bc90fea 2022-11-21)cargo-watch
uses. According to thecargo-watch
authors, it would be best if the patch could be released for4.x
version if that possible..IsFile
event, while it should not. watchexec/cargo-watch#242What you did (as detailed as you can)
I'm using
cargo-watch
8.1.1 (because 8.3.0 does not work on new macOS). Recently, our build script, which uses cargo-watch under the hood, started looping indefinitely. After debugging it turned out, that when usingstd::fs::copy("a.txt", "b.txt")
on macOS, a file system eventIsFile
is sometimes emitted on the source file ("a.txt"
). The term "sometimes" is better explained here. Our build script is copying some files to target directory, which causes the sources to emit this event, which causescargo-watch
to re-run the whole operation again. Thecargo-watch
issue, where the authors asked me to post issue here can be found here: watchexec/cargo-watch#242The text was updated successfully, but these errors were encountered: