Add a warning and fallback on polling mode if limit exceeded

Works only on linux (not sure how error is named on other systems):
```
*** System notification limit is too small, falling back to polling
mode.
*** For better performance increase system limit:
   sysctl fs.inotify.max_user_watches=524288
*** Polling for changes every 1000 ms
```

Fixes #62
This commit is contained in:
Paul Colomiets 2018-08-01 18:36:19 +03:00
parent b9822266db
commit a2d0a251da
1 changed files with 33 additions and 2 deletions

View File

@ -8,6 +8,7 @@ use cli;
use env_logger;
use gitignore;
use log;
use notify::Error;
use notification_filter::NotificationFilter;
use process::{self, Process};
use signal::{self, Signal};
@ -28,6 +29,22 @@ fn init_logger(debug: bool) {
log_builder.init().expect("unable to initialize logger");
}
#[cfg(target_os="linux")]
fn should_switch_to_poll(e: &Error) -> bool {
use nix::libc;
match e {
&Error::Io(ref e) if e.raw_os_error() == Some(libc::ENOSPC) => true,
_ => false,
}
}
#[cfg(not(target_os="linux"))]
fn should_switch_to_poll(_: &Error) -> bool {
// not known conditions to switch
false
}
pub fn run(args: cli::Args) {
let child_process: Arc<RwLock<Option<Process>>> = Arc::new(RwLock::new(None));
let weak_child = Arc::downgrade(&child_process);
@ -69,8 +86,22 @@ pub fn run(args: cli::Args) {
.expect("unable to create notification filter");
let (tx, rx) = channel();
let watcher =
Watcher::new(tx, &paths, args.poll, args.poll_interval).expect("unable to create watcher");
let watcher = match Watcher::new(tx.clone(), &paths, args.poll, args.poll_interval) {
Ok(watcher) => watcher,
Err(ref e) if !args.poll && should_switch_to_poll(e) => {
warn!("System notification limit is too small, \
falling back to polling mode.");
if cfg!(target_os="linux") {
warn!("For better performance increase system limit: \n \
sysctl fs.inotify.max_user_watches=524288");
}
Watcher::new(tx, &paths, true, args.poll_interval)
.expect("polling watcher should always work")
}
Err(e) => {
panic!("Error setting up watcher: {}", e);
}
};
if watcher.is_polling() {
warn!("Polling for changes every {} ms", args.poll_interval);