Skip to content

Conversation

@withzombies
Copy link

Adds EventKindMask, a bitflags-based type that allows users to configure which event kinds they want to receive. This is configured via Config::with_event_kinds().

This feature allows filtering at the source. On Linux (inotify), filtering happens at the kernel level via WatchMask translation, so unwanted events never reach userspace. On other backends, filtering is applied early in the event pipeline.

Existing users shouldn't see any breaking changes. The default (EventKindMask::ALL) should preserve existing behavior.

Usage

use notify::{Config, EventKindMask, RecommendedWatcher, Watcher};

// Exclude access events (OPEN/CLOSE) - kernel-level on Linux
let config = Config::default().with_event_kinds(EventKindMask::CORE);

// Or be more selective
let config = Config::default()
    .with_event_kinds(EventKindMask::CREATE | EventKindMask::REMOVE);

let mut watcher = RecommendedWatcher::new(tx, config)?;

Changes

  • New EventKindMask type in notify-types with flags: CREATE, REMOVE, MODIFY_DATA, MODIFY_META, MODIFY_NAME, ACCESS_OPEN, ACCESS_CLOSE, ACCESS_CLOSE_NOWRITE
  • Composite masks: CORE (excludes access), ALL (everything)
  • Default is ALL for backward compatibility
  • Implemented in all backends: inotify (kernel), kqueue, FSEvents, Windows, PollWatcher (userspace)
  • Includes examples and tests for each backend

- Change EventKindMask::default() from CORE to ALL to match
  Config::default().event_kinds()
- Add userspace event filtering to PollWatcher via EventEmitter
- Filter events in emit_ok() using EventKindMask::matches()
- Error events always pass through (not filtered)
- Add test verifying CREATE-only mask filters MODIFY events
- Add cross-crate consistency test for defaults

This is part of the EventKindMask cross-platform filtering feature.
PollWatcher now respects the event_kinds config, filtering events
before delivery to the user's handler.
Adds userspace event filtering to the kqueue backend by storing the
EventKindMask from Config and checking events against it before
delivering to the handler. This follows the same pattern established
in PollWatcher.

- Store event_kinds in EventLoop struct
- Pass event_kinds from Config through the constructor chain
- Filter OK events before calling handle_event(), errors pass through
- Add test for filtering behavior (requires BSD/macOS to run)
Add event filtering to the FSEvents (macOS) backend by calling
EventKindMask::matches() before delivering events to the handler.
This follows the same pattern established in kqueue and PollWatcher.

Changes:
- Add event_kinds field to FsEventWatcher and StreamContextInfo
- Pass event_kinds from Config through to the callback context
- Filter events in callback_impl based on the mask
- Add test for filtering behavior
Thread EventKindMask through ReadDirectoryChangesServer and start_read
to filter events before delivery. Events that don't match the mask are
silently dropped, while errors always pass through.
Change test infrastructure ChannelConfig::default() to use Config::default()
which includes EventKindMask::ALL instead of CORE. This ensures tests cover
all event types including Access events.

Updated inotify tests to use wait_ordered() instead of wait_ordered_exact()
where appropriate, since with ALL events we may get directory access events
that are timing-dependent. Tests that check for absence of specific events
now filter out Access events to focus on the behavior being tested.
kqueue uses userspace filtering via EventKindMask::matches(), only inotify
has kernel-level support via WatchMask translation.

Updated documentation in:
- notify-types/src/event.rs: EventKindMask doc comment
- notify/src/config.rs: with_event_kinds() doc comment
Use blocking recv_timeout instead of try_iter to avoid race condition
between poll thread processing the message and test collecting events.
@greged93
Copy link

Would really love this feature to be merged. Should this be on the Config or on the Watcher::watch?

@withzombies
Copy link
Author

Would really love this feature to be merged. Should this be on the Config or on the Watcher::watch?

I went with Config because it better fit my use case. I wasn't trying to have a mix of event levels. I think if we want different event levels we could start a few watchers?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants