Reinstate the kqueue backend in FileWatcher
In #1644 (closed), we discovered the FileWatcher
implementation (used for watching config source files and directories for changes) does not work properly on FreeBSD and macOS because of a bug in notify
's kqueue-based backend: https://github.com/notify-rs/notify/issues/644
As a temporary workaround, we switched to using PollWatcher
on all platforms other than windows, linux, and android (we're not sure if the FileWatcher
behaves correctly on windows, but we know that it works well with the inotify
backend. If the default windows backend turns out to be broken as well, we can replace it with a polling watcher too).
The polling watcher is less efficient than the native alternative (it periodically re-reads the watched files/directories to see if they changed), so it's not an ideal long-term solution. We should try to reinstate the kqueue
backend for macOS and *BSD, or implement our own kqueue
watcher.
To do so, we could
- patch
notify
's kqueue watcher implementation to better approximate inotify behavior when watching non-recursively. When adding a directory to the non-recursive watch list, it'll need to take note of all the files in that directory. When receiving a kqueue "write" event for that directory, it will need to "diff" the previous state of the directory with the current one, and emit an event for each file/directory that has changed. This is of course racy, because you could modify the contents of the directory after adding the directory to the watch list, but before starting the watcher. - implement a simpler version of the
FileWatcher
that's less strict about event handling: we can tolerate some spurious config reloads, so we could perhaps ourkqueue
replacement could be less smart (it won't need to accurately fill out thenotify::Event
with the paths that triggered the event, because we don't really care about those. We just need to know whether to re-read the config, so a simple "something changed" event would suffice). This will involve simplifying theFileWatcher
logic too (it currently suppresses any events that aren't related to the exact files/directories the user set a watch for).