-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
feat(watcher): add support for poll watcher #21290
base: master
Are you sure you want to change the base?
feat(watcher): add support for poll watcher #21290
Conversation
3773b14
to
ae66312
Compare
4c926d0
to
1802ece
Compare
interval: NonZeroU64, | ||
) -> config::watcher::WatcherConfig { | ||
match method { | ||
WatchConfigMethod::Inotify => config::watcher::WatcherConfig::RecommendedWatcher, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, take a look into my comment about this in your closed PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we put this as Recommended
or any thing that comes to ur mind? @jszwedko
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, that would fit
} | ||
WatcherConfig::PollWatcher(interval) => { | ||
let config = | ||
notify::Config::default().with_poll_interval(Duration::from_secs(*interval)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we allow the user to specify compare_contents
? https://docs.rs/notify/latest/notify/struct.Config.html#method.with_compare_contents
maybe another argument? Im afraid we are adding too much arguments for this though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd vote against it being user controllable and hope for it to just have a sane default. I can't think of a scenario where I'd wanna toggle it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We found issues in openshift environments where the inotify watcher was constantly triggered and the file contents did not change at all. In this case, we would like to hash the contents to check if it really changed before reloading vector config. I think having sane defaults is good (for example, this would default to false), but there are situations where this is useful
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would there be a downside to always hashing the changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, as the docs I pointed states:
By enabling this feature, performance will be significantly impacted as all files will need to be read and hashed at each poll_interval.
I prefer that downside to be opt-in
|
||
enum Watcher { | ||
/// recommended watcher for os, usually inotify for linux based systems | ||
RecommendedWatcher(notify::RecommendedWatcher), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be more idiomatic to use only RecommendedWatcher
, adding use notify::RecommendedWatcher
and the top of the file (as you has before)
RecommendedWatcher(notify::RecommendedWatcher), | |
RecommendedWatcher(RecommendedWatcher), |
My previous suggestion about this was only about the notify::Watcher
trait, and because it conflicted with your Watcher
enum
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the Watcher
is necessary for use watch
method on PollWatcher
and RecommendWatcher
. removing that makes watch
method is not defined error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can use notify::RecommendedWatcher
and use notify::PollingWatcher
, that have nothing related to what you're saying about the Watcher
trait. The previous code imported those two structs
and indeed, maybe you need to use notify::Watcher
to use the watch
method
/// recommended watcher for os, usually inotify for linux based systems | ||
RecommendedWatcher(notify::RecommendedWatcher), | ||
/// poll based watcher. for watching files from NFS. | ||
PollWatcher(notify::PollWatcher), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PollWatcher(notify::PollWatcher), | |
PollWatcher(PollWatcher), |
|
||
fn watch(&mut self, path: &Path, recursive_mode: RecursiveMode) -> Result<(), Error> { | ||
match self { | ||
&mut Watcher::RecommendedWatcher(ref mut watcher) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can get rid of this (In the other match arm too)
This behaviour was improved a few years ago
Read about it here: https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md
&mut Watcher::RecommendedWatcher(ref mut watcher) => { | |
Watcher::RecommendedWatcher(watcher) => { |
match watcher_conf { | ||
WatcherConfig::RecommendedWatcher => { | ||
let recommended_watcher = recommended_watcher(sender)?; | ||
let mut watcher = Watcher::RecommendedWatcher(recommended_watcher); | ||
watcher.add_paths(config_paths)?; | ||
Ok((watcher, receiver)) | ||
} | ||
WatcherConfig::PollWatcher(interval) => { | ||
let config = | ||
notify::Config::default().with_poll_interval(Duration::from_secs(*interval)); | ||
let poll_watcher = notify::PollWatcher::new(sender, config)?; | ||
let mut watcher = Watcher::PollWatcher(poll_watcher); | ||
watcher.add_paths(config_paths)?; | ||
Ok((watcher, receiver)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can take
watcher.add_paths(config_paths)?;
Ok((watcher, receiver))
out of the match branches
match watcher_conf { | |
WatcherConfig::RecommendedWatcher => { | |
let recommended_watcher = recommended_watcher(sender)?; | |
let mut watcher = Watcher::RecommendedWatcher(recommended_watcher); | |
watcher.add_paths(config_paths)?; | |
Ok((watcher, receiver)) | |
} | |
WatcherConfig::PollWatcher(interval) => { | |
let config = | |
notify::Config::default().with_poll_interval(Duration::from_secs(*interval)); | |
let poll_watcher = notify::PollWatcher::new(sender, config)?; | |
let mut watcher = Watcher::PollWatcher(poll_watcher); | |
watcher.add_paths(config_paths)?; | |
Ok((watcher, receiver)) | |
} | |
let watcher = match watcher_conf { | |
WatcherConfig::RecommendedWatcher => { | |
let recommended_watcher = recommended_watcher(sender)?; | |
Watcher::RecommendedWatcher(recommended_watcher) | |
} | |
WatcherConfig::PollWatcher(interval) => { | |
let config = | |
notify::Config::default().with_poll_interval(Duration::from_secs(*interval)); | |
let poll_watcher = notify::PollWatcher::new(sender, config)?; | |
Watcher::PollWatcher(poll_watcher) | |
}; | |
watcher.add_paths(config_paths)?; | |
Ok((watcher, receiver)) | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, this seems elegant. i'll do that
env = "VECTOR_WATCH_CONFIG_POLL_INTERVAL_SECONDS", | ||
default_value = "30" | ||
)] | ||
pub watch_config_poll_interval_seconds: NonZeroU64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should update this documentation to explain the polling watcher and when to use it
https://vector.dev/docs/administration/management/#automatic-reloading-on-configuration-change
But first lets see what maintainers think about documenting this
Co-authored-by: Jorge Hermo <[email protected]>
Closes #21111