Skip to content

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 our kqueue replacement could be less smart (it won't need to accurately fill out the notify::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 the FileWatcher logic too (it currently suppresses any events that aren't related to the exact files/directories the user set a watch for).