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
Optional Buffered Events channel. #550
Conversation
What kind of values do you want to set |
It varies, for our existing fork we leave it to zero and provide a configuration parameter in the application to crank it up. What we found through pretty aggressive testing is that when the kernel config parameters are sane leaving the channel as unbuffered and forcing the kernel buffer to do its thing was a better solution. The kernel dedups events and is generally really fast. However, we have a few users that have watched log directories with 10s of thousands of files that all get rotated all at once via logrotate (I know, but we can't control what they do). They are also running unpriveleged on an older RedHat system with small kernel buffers. So we have them optionally crank that channel buffer (100k+) and then the log rotation becomes entirely survivable. Long story short, leaving it to zero covers 99.5% of uses but having a configurable parameter lets us survive the 0.5% of dumb cases. I don't think an always buffered channel should be the default. |
Right; "hundreds of thousands" is rather a lot. If it was something like 100 then I'd be okay with just allocating that. My main concern is that we will now have two kind of My idea was that all options would be per-watch rather than per-watcher, but with None of this is in any tagged release yet, so we can still change the names or behaviour of anything here. I need to think what the best solution for this is. Some options might be:
I'm kind of leaning towards option 3 or 4, unless someone can think of another option we really want to add in the future. |
I totally get it. I struggled with what the "right" thing was. The only reason I thought option style parameters might be worth while is this issue: #431 An options parameters thingy might allow shoehorning in something like that through an option. We love this library and my number 1 priority is to minimize any headaches and ambiguities for you (and your other users). |
#431 can be a per-watch (rather than per-watcher) option I think? I'm not even sure we need an option for that in first place; just always flushing is probably fine (cc: @horahoradev). |
channel with default size always block sending if data is not received. So this solution can be used to make seamless operations. |
So personally I'd lean towards Do you want to rewrite the PR @kris-watts-gravwell? Otherwise I'll take a look at it at some point. This would basically be the commit from your fork, with FEN support that has been added since, the test you added here, and the API docs from this PR which explain why you might want this function. If you do, a few small remarks:
Another option not mentioned in my previous comment would be a |
I will rewrite the pr and get the comments and docs addressed too. Thanks! |
I'd just be very wary of introducing a deadlock if the client's event receiver has already exited before watcher.Close() is called. If the events buffer is already full, and has no handler, and we're only returning from close after we flush all outstanding events, then Close() would block indefinitely, which could introduce dangerous behavior. |
…ying to update the existing NewWatcher
ok, I think i have this PR into a state that matches the consensus. Just adding a new "NewBufferedWatcher" call which can generate a Watcher with a user land Event buffer. I tried to add a comment block that was adequately scary enough that users will only use the new interface if they know exactly what they are doing. |
One of the tests consistently fails if I run the tests with a buffered watcher:
Not yet sure if that's a bug in the testcase or code 🤔 I've seen some intermittent failures on this before, so could be a bug in the test code that just shows up more consistently here. I'll have to look in to it. I'll also work on refactoring things a bit so it always runs all tests against both a regular and buffered watcher. Made my changes over here: https://github.com/fsnotify/fsnotify/commits/configOptions |
Merged via #572; I finally spent some time fixing up the tests. You do need to do |
This PR slightly overhauls the NewWatcher() API so that a list of Options functions can be provided. Currently there is only one configured option but there are a few issues asking for more configuration options so this should allow for an extensible method to add configuration options to NewWatcher.
The goals for this PR:
The motivation for this PR
We make extensive use of the fsnotify library but continually run into situations with older RedHat installations where the kernel fsnotify buffer is not large enough to accommodate high load scenarios like log file rotation and the end user cannot modify the kernel parameters. We have been running a fork that created a userland event channel buffer and found that we are able to deal with very large bursts of fsnotify events without being forced to catch errors and recover.
The userland channel buffer will never be as fast as the kernel buffer, and in most cases straight won't be used, but this PR gives users of the library the option to add some padding without changing kernel parameters.