notify-rs/notify

Using kqueue on mac can result in "Too many open files (os error 24)"

Opened this issue · 0 comments

System details

  • OS/Platform name and version:

    Apple M1 Max - macOs Sonoma 14.4.1

  • Rust version (if building from source): rustc --version:

    rustc 1.79.0-nightly (1cec373f6 2024-04-16)

  • Notify version (or commit hash if building from git):

    notify = "6.1.1"

What you did

I tried using the macos_kqueue feature via this in my Cargo.toml file:

notify = { version = "6.1.1", default-features = false, features = ["macos_kqueue"] }

I then set up the watcher to watch 300 files. (see code sample at the end of this post)

What you expected

I expected notify to watch the files and trigger when they changed

What happened

Instead, I got this error as soon as I started the process

Error: Error { kind: Generic("Too many open files (os error 24) about [\"/Users/alan/Desktop/notify-test/./test_files/268.txt\"]"), paths: [] }

Notes

  • This is the script I'm using to run the tests:
[dependencies]
notify = { version = "6.1.1", default-features = false, features = ["macos_kqueue"] }
use notify::{Watcher, RecursiveMode, Result};
use std::path::PathBuf;
use std::fs;

fn main() -> Result<()> {
    let test_dir = PathBuf::from("test_files");
    fs::create_dir_all(&test_dir).unwrap();

    for f in 0..300 {
        let file_path = test_dir.clone().join(format!("{}.txt", f));
        fs::write(file_path, "x").unwrap();
    }

    let mut watcher = notify::recommended_watcher(|res| {
        match res {
           Ok(event) => println!("event: {:?}", event),
           Err(e) => println!("watch error: {:?}", e),
        }
    })?;

    watcher.watch(&test_dir, RecursiveMode::Recursive)?;
    Ok(())
}
  • I found this issue which talks about the max number of allowed files imposed by the os. My default from ulimit -n was 256. If I change the limit to 500 with ulimit -n 500 the process works fine. If I then change it back with ulimit -n 256 it fails again with the same error

  • I tried splitting the files into multiple different directories and adding each directory individually (e.g. watcher.watch(&test_dir_a, RecursiveMode::Recursive)?;, watcher.watch(&test_dir_b, RecursiveMode::Recursive)?;, etc...). The same issue occurred when I got over the ulimit number

  • This issue on mdBook mentions a "Too many open files" error but doesn't go into details. That makes me think it's not just me that's having the issue

  • I also see this issue which sounds like same issue but for BSD instead of mac

  • The docs page example for using notify with tokio shows using notify = { version = "6.1.1", default-features = false, features = ["macos_kqueue"] }. That's what got me started down this path. Might be worth changing that example to use macos_fsevent instead for the time being