-
Notifications
You must be signed in to change notification settings - Fork 30.3k
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
bug: on MacOS, fs.watch
emits "change"
event when access timestamp is updated
#49916
Comments
It's "change" because the metadata changed - atime is metadata. The kernel reports It's possible the behavior changed in newer macos releases. I only test on an old Intel MBA. |
Forgot to mention: 66560 is |
So it turns out I didn't read the docs 😅 :
So I guess my case is from This is tricky. Responding to I wonder if this can be solved at a higher level? As it is, it seems like the user workaround has to be to stat the files in the user-provided handler. Which might be hard to convince tooling maintainers to do. |
This comment was marked as off-topic.
This comment was marked as off-topic.
Ah... your original message made it seem like watchee.js was a directory because of the So, fsevents only works on directories, that's why libuv falls back to kevent/kqueue when watching a single file - and yes, it's pretty limited. The change and rename events correspond directly to the UV_CHANGE and UV_RENAME constants. Speaking with my libuv maintainer hat on, I don't foresee us adding a UV_ATTRIB flag because then we have to start tracking metadata and end up implementing half of uv_fs_poll_t / fs.watchFile. I'll take the liberty of closing this because things are working as expected. The caveats about fs.watch's platform differences are mentioned in the documentation. It was specifically added as a performance optimization over fs.watchFile for people who are prepared to deal with its non-uniform behavior. The workaround to get the desired behavior is indeed as you say: either stat the file after an event or switch to fs.watchFile, which does that automatically for you. |
I just sampled Go's
- notify = { version = "6.1.1", features = ["macos_kqueue"] }
+ notify = { version = "6.1.1", features = ["macos_fsevent"] }
It sounds like neither are going to happen in Node.js unfortunately (and is really an issue with |
Version
v20.3.1
Platform
Darwin macbook-air 22.5.0 Darwin Kernel Version 22.5.0: Thu Jun 8 22:22:19 PDT 2023; root:xnu-8796.121.3~7/RELEASE_ARM64_T8103 arm64
Subsystem
fs
What steps will reproduce the bug?
Contents of
repro.js
:The
stat -x
verifies that only the access timestamp changed, not the modified.How often does it reproduce? Is there a required condition?
Consistently.
What is the expected behavior? Why is that the expected behavior?
The expected behavior is for accesses to either emit a different type of event
"access"
, or no event at all. I believe the latter is the intended behavior, as that's what happens on WSL.The reason this is expected is because of the meaning of the word
"change"
, as well as the real-world usage of this API (related: microsoft/TypeScript#52876)What do you see instead?
Repro script prints out
File package.json has changed
in response totouch -a
.In the wild, this causes files to be rebuilt.
Additional information
This issue doesn't happen on WSL. I haven't tried Windows.
Following Apple's fsevents guide, gives me flags 66560 for
touch
and no event fortouch -a
. I tried this with both0xffffffff
andkFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents
.Let me try making a debug build of
main
to see what Node.js does differently.The text was updated successfully, but these errors were encountered: