Skip to content

Comments

feat: introduce Watcher::paths_mut for adding/removing paths in batch#692

Merged
JohnTitor merged 7 commits intonotify-rs:mainfrom
branchseer:watch-batch
Jul 1, 2025
Merged

feat: introduce Watcher::paths_mut for adding/removing paths in batch#692
JohnTitor merged 7 commits intonotify-rs:mainfrom
branchseer:watch-batch

Conversation

@branchseer
Copy link
Contributor

fixes #653.

I can add tests once the added API is agreed upon.

@Boshen
Copy link

Boshen commented Jun 30, 2025

/// [#166]: https://github.com/notify-rs/notify/issues/166
fn watch(&mut self, path: &Path, recursive_mode: RecursiveMode) -> Result<()>;

/// Begin to add/remove paths to watch.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Begin to add/remove paths to watch.
/// Add/remove paths to watch.

@JohnTitor
Copy link
Member

I can add tests once the added API is agreed upon.

Yeah, looks cool. Not necessary but adding examples would also be great.

@branchseer
Copy link
Contributor Author

@JohnTitor Test & example added

@JohnTitor
Copy link
Member

Seems there are some typos, check CI.

Copy link
Member

@JohnTitor JohnTitor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thank you!

@JohnTitor JohnTitor merged commit d824023 into notify-rs:main Jul 1, 2025
17 checks passed
@TimNN
Copy link

TimNN commented Jul 1, 2025

Thanks! But I wanted to double-check that this handles all edge cases appropriately:

  • What happens if commit is called twice?
  • What happens if add or remove are called after commit?
  • What happens if PathsMut is dropped without calling commit?

@branchseer
Copy link
Contributor Author

What happens if commit is called twice?

The second commit ensures the changes since the first one are applied (maybe earlier)

What happens if add or remove are called after commit?

Unspecified behaviour. May or may not be applied depending on the implementation.

What happens if PathsMut is dropped without calling commit?

Unspecified behaviour. May or may not be applied depending on the implementation.

I intentionally leave the semantic of commit vague to allow each backend to provide its most performant implementation.

All the doc guarantees is previously added/removed paths are applied after commit is called (maybe earlier). The behaviour of "uncommitted" changes is not specified. The implementation is free to ignore them or not.

In reality, for FSEvents watcher, the changes aren't applied until commit; for all the other backends, a change is applied as soon as PathsMut::add/PathsMut::watch is called, and commit is a noop. (again, these are implementation details not documented behaviours).

@Boshen
Copy link

Boshen commented Jul 2, 2025

Thank you for merging this.

@dfaust will you be able to publish a new release?

@TimNN
Copy link

TimNN commented Jul 2, 2025

Ack, thanks for clarifying @branchseer!

For FSEvents, I was mainly concerned that calling fn run while the watcher is already running could cause problems, or that modifying the watched paths while the watcher is running could be problematic.

For example, fn stop includes some code to explicitly terminate the previous runloop.

If fn run is called twice (e.g. due to fn commit being called twice), it looks like that termination code doesn't run. (Maybe that's fine, I haven't tested it and am not familiar enough with the code to properly judge this).

Also: paths seems to be passed to FSEventStreamCreate but also modified in fn append_path. Calling fn add after fn commit means that's it's now possible for paths to be modified while the watcher is running. (Again, maybe that's fine (I couldn't tell from the Apple documentation) because FSEventStreamCreate makes a copy of the paths or only reads them during initialization, but I could also easily see this cause problems).

@branchseer
Copy link
Contributor Author

branchseer commented Jul 2, 2025

I didn't notice that run and stop can be unbalanced. Thanks for pointing it out. @TimNN

I have submitted a fix: #695. @JohnTitor could you help review again? Thank you.

github-merge-queue bot pushed a commit to rolldown/rolldown that referenced this pull request Jul 3, 2025
riberk added a commit to riberk/notify that referenced this pull request Jul 18, 2025
The feature to add / remove paths to watch in batch was introduced in notify-rs#692
There was a problem with the implementation: if you drop the instance without `commit` it may leave the watcher in an inconsistent state (especially fsevents).

This commit changes behavior and api and introduces `update_watches` method of the `Watcher` trait, which do the same stuff but in more consistent way.
The `paths_mut` method was kept, but returning struct is just a builder for the method `update_watches` that will be called by `PathsMut::commit`

related notify-rs#659
closes notify-rs#704
riberk added a commit to riberk/notify that referenced this pull request Jul 18, 2025
The feature to add / remove paths to watch in batch was introduced in notify-rs#692
There was a problem with the implementation: if you drop the instance without `commit` it may leave the watcher in an inconsistent state (especially fsevents).

This commit changes behavior and api and introduces `update_watches` method of the `Watcher` trait, which do the same stuff but in more consistent way.
The `paths_mut` method was kept, but returning struct is just a builder for the method `update_watches` that will be called by `PathsMut::commit`

related notify-rs#653
closes notify-rs#704
riberk added a commit to riberk/notify that referenced this pull request Jul 18, 2025
The feature to add / remove paths to watch in batch was introduced in notify-rs#692
There was a problem with the implementation: if you drop the instance without `commit` it may leave the watcher in an inconsistent state (especially fsevents).

This commit changes behavior and api and introduces `update_watches` method of the `Watcher` trait, which do the same stuff but in more consistent way.
The `paths_mut` method was kept, but returning struct is just a builder for the method `update_watches` that will be called by `PathsMut::commit`

related notify-rs#653
closes notify-rs#704
riberk added a commit to riberk/notify that referenced this pull request Jul 18, 2025
The feature to add / remove paths to watch in batch was introduced in notify-rs#692
There was a problem with the implementation: if you drop the instance without `commit` it may leave the watcher in an inconsistent state (especially fsevents).

This commit changes behavior and api and introduces `update_watches` method of the `Watcher` trait, which do the same stuff but in more consistent way.
The `paths_mut` method was kept, but returning struct is just a builder for the method `update_watches` that will be called by `PathsMut::commit`

related notify-rs#653
closes notify-rs#704
riberk added a commit to riberk/notify that referenced this pull request Jul 18, 2025
The feature to add / remove paths to watch in batch was introduced in notify-rs#692
There was a problem with the implementation: if you drop the instance without `commit` it may leave the watcher in an inconsistent state (especially fsevents).

This commit changes behavior and api and introduces `update_watches` method of the `Watcher` trait, which do the same stuff but in more consistent way.
The `paths_mut` method was kept, but returning struct is just a builder for the method `update_watches` that will be called by `PathsMut::commit`

related notify-rs#653
closes notify-rs#704
riberk added a commit to riberk/notify that referenced this pull request Jul 18, 2025
The feature to add / remove paths to watch in batch was introduced in notify-rs#692
There was a problem with the implementation: if you drop the instance without `commit` it may leave the watcher in an inconsistent state (especially fsevents).

This commit changes behavior and api and introduces `update_watches` method of the `Watcher` trait, which do the same stuff but in more consistent way.
The `paths_mut` method was kept, but returning struct is just a builder for the method `update_watches` that will be called by `PathsMut::commit`

related notify-rs#653
closes notify-rs#704
riberk added a commit to riberk/notify that referenced this pull request Jul 18, 2025
The feature to add / remove paths to watch in batch was introduced in notify-rs#692
There was a problem with the implementation: if you drop the instance without `commit` it may leave the watcher in an inconsistent state (especially fsevents).

This commit changes behavior and api and introduces `update_watches` method of the `Watcher` trait, which do the same stuff but in more consistent way.
The `paths_mut` method was kept, but returning struct is just a builder for the method `update_watches` that will be called by `PathsMut::commit`

related notify-rs#653
closes notify-rs#704
riberk added a commit to riberk/notify that referenced this pull request Oct 24, 2025
The feature to add / remove paths to watch in batch was introduced in notify-rs#692
There was a problem with the implementation: if you drop the instance without `commit` it may leave the watcher in an inconsistent state (especially fsevents).

This commit changes behavior and api and introduces `update_watches` method of the `Watcher` trait, which do the same stuff but in more consistent way.
The `paths_mut` method was kept, but returning struct is just a builder for the method `update_watches` that will be called by `PathsMut::commit`

related notify-rs#653
closes notify-rs#704
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.

[Feature Request]: provider a watch multiple files api to instead of multiple call Watcher#watch

5 participants