-
Notifications
You must be signed in to change notification settings - Fork 229
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
Large scale watching of paths appears to drop/miss events #412
Comments
I've tried this with files and directories. It seems like the watcher doesn't receive or maybe invoke the handler for a subset of the paths if enough changes happen to a large enough set of files. On my Mac, I had to crank the file count to 1500 to see this happen consistently. On Windows, it was a bit slower and I could reliably hit this with ~500 paths. Is there a better way to handle this? Should I not expect notify to handle a large number of paths at once? I know that some recommendations have been to watch parent directories to detect changes within, but my project is a server that can have any number of paths watched at any time; so, I want to make sure that I understand the limits and if there's anything I can do to handle this better! 😄 |
Can you try running your example with --release mode ? You seem to ignore any send-errors, is there a reason this panics ? Also if possible don't print anything inside the hot code, this requires a global lock to be acquired for every println!. So this can certainly generate misses and create contention between notifies callback thread and your file changer. I looked over your code, which does seem to be fine. Watching a folder or a specific set of files may not really differ depending on the OS used, though it may also not emit all events (file deletion, move etc), which is also dependent on the OS. Thus we recommend watching the parent of the thing you're actually interested in. |
I tried doing a release test on my Mac with no print statements and it's still failing: I've also tested it where any event for a path will count instead of modification. That helps, but if you throw enough paths at the problem (or use windows), then it still fails. I guess my next step is to watch the actual parent path as you recommended and then filter events if they are for a child path that we're actively watching. |
Oh, as for ignoring the send error, when I had it panic with an |
Well it shouldn't reach capacity. And if you're ignoring send errors, you'll certainly not receive all events in your test, as you're apparently not sending all events over the channel. |
@0xpr03 sorry, ignore the capacity thing as I don't think it's relevant for this specific challenge since the sender I'm using in the example is unbounded. I modified the code example to create a bunch of directories with a single file within each like this:
From there, I watched the parent directories of the files such as I also removed any filtering of events by kind, so I'm just checking to see if I get any event for a given file. Lastly, I added a sleep of 1ms per attempt to receive an event from the main test thread, just in case my loop was spiking the CPU or something that would affect the notify thread. This does appear to help Windows out quite a lot, which was the biggest troublemaker when it came to missing events. On Mac, I'm still having the problem of missing events. Is there anything else I can do in this case? I don't expect to have 1500 separate paths being watched at a time, but want to check if there's anything else that I could be doing better to use the library. |
It's probably not what you want to hear.. But I'll let the manpage speak for me:
(another one for the Known Issues ) I think this also applies to MacOS. (The If I'm reading this right you also don't get any errors (EINVAL), so we're not accidentally using a buffer that is too tiny. TLDR: Use the PollWatcher if you want to be super certain that no events are missed, but you won't get very precise informations (can only tell your diffs based on files in folder and last-changed timestamps / content changes). |
This is handled here. Basically, every time you receive Other event with Rescan flag set, you need to rescan everything you watch. I believe this behavior should be reflected more explicitly in documentation. Edit: Apparently it is addressed in #434 |
System details
rustc --version
: rustc 1.60.0 (7737e0b5c 2022-04-04)Mac
M1 Macbook Air from 2020.
Windows
Traditional Windows 11 machine.
Linux
Running Alpine Linux using Mac Parallels on an M1 Mac, which means Alpine is using ARM.
What you did (as detailed as you can)
Example repo where you can run test: https://github.com/chipsenkbeil/notify-stress-test
notify::recommended_watcher
std::sync::mpsc::Sender
std::sync::mpsc::Receiver
std::sync::mpsc::Receiver
What you expected
Path modifications or other events show up for watched paths at scale. For example, if watching 1500 individual files, modifying each file would result in some event being captured and passed along.
What happened
With enough different paths being watched, events start to be missing or dropped. For example, watching 1500 individual files, modifying each file, 246 paths were never reported as modified.
The text was updated successfully, but these errors were encountered: