Skip to content
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

inotify: don't ignore events for files that don't exist #470

Merged
merged 1 commit into from Jul 29, 2022
Merged

Conversation

arp242
Copy link
Member

@arp242 arp242 commented Jul 24, 2022

This is quite an odd check, leading to an inconsistent event stream,
which also doesn't match what other platforms do. If you do a "CREATE +
MODIFY + REMOVE" in quick succession then you probably want all three
events. If you don't want to operate on non-existing files, then you can
check this in your application code.

You need to do that already, since this check is far from reliable. In
the time between this check and the application code doing something
with an event the file may have been deleted already.

I looked a bit at the history of this, and looks like it was added in
2013 with cc2c34e; issue 36 refers to this issue on the old repo, which
mentions it fixes a memory leak: howeyc/fsnotify#36

I can't reproduce that at all; using the CLI from #463 modified to print
the memory and running:

for i in $(seq 0 10000); { touch $i; rm $i }

Memory stays at about 100/110K in both the current main branch and this.

So I think it should be safe to remove.

This is quite an odd check, leading to an inconsistent event stream,
which also doesn't match what other platforms do. If you do a "CREATE +
MODIFY + REMOVE" in quick succession then you probably *want* all three
events. If you don't want to operate on non-existing files, then you can
check this in your application code.

You need to do that already, since this check is far from reliable. In
the time between this check and the application code doing something
with an event the file may have been deleted already.

I looked a bit at the history of this, and looks like it was added in
2013 with cc2c34e; issue 36 refers to this issue on the old repo, which
mentions it fixes a memory leak: howeyc/fsnotify#36

I can't reproduce that at all; using the CLI from #463 modified to print
the memory and running:

	for i in $(seq 0 10000); { touch $i; rm $i }

Memory stays at about 100/110K in both the current main branch and this.

So I think it should be safe to remove.
arp242 added a commit that referenced this pull request Jul 25, 2022
This adds a recursive watcher for inotify; per my suggestion in [1] it
uses the "/..." syntax in the path to indicate recursive watches,
similar to how Go tools work:

	w, _ := fsnotify.NewWatcher()
	w.Add("some/dir/...")

This will watch "some/dir" as well as any subdirectories of "some/dir".

The upshot of using a syntax like this is that we can:

1. With AddRecursive(path string) adding new Add* methods would become
   hard; for example AddMask("path", fsnotify.Create) to only get CREATE
   events; we'd then also have to add AddMaskRecursive(). Plus we'd
   have to add a RemoveRecursive() as well.

2. With Watcher.SetRecursive() like in #339 it's not possible to add
   some paths recursively and others non-recursively, which may be
   useful in some cases. Also, it makes it a bit easier to accept user
   input; in the CLI or config you can set "dir/..." and just pass that
   as-is to fsnotify, without applications having to write special code.

For other watchers it will return ErrRecursionUnsupported for now;
Windows support is already mostly finished in #339, and kqueue can be
added in much the same way as inotify in a future PR.

I also moved all test helpers to helper_test.go, and added a bunch of
"shell-like" functions so you're not forever typing error checks and
filepath.Join(). The new "eventCollector" is also useful in tests to
conveniently collect a slice of events.

TODO:

- Also support recursion in Remove(), and deal with paths added with
  "...". I just updated the documentation but didn't actually implement
  anything.

- A few test cases don't seem quite right; want to get #470 merged first
  as it really confuses things.

- Maybe think of a few more test cases.

[1]: #339 (comment)
@arp242 arp242 merged commit 1a7b6ef into main Jul 29, 2022
@arp242 arp242 deleted the lstat branch July 29, 2022 18:31
arp242 added a commit that referenced this pull request Aug 4, 2022
This adds a recursive watcher for inotify; per my suggestion in [1] it
uses the "/..." syntax in the path to indicate recursive watches,
similar to how Go tools work:

	w, _ := fsnotify.NewWatcher()
	w.Add("some/dir/...")

This will watch "some/dir" as well as any subdirectories of "some/dir".

The upshot of using a syntax like this is that we can:

1. With AddRecursive(path string) adding new Add* methods would become
   hard; for example AddMask("path", fsnotify.Create) to only get CREATE
   events; we'd then also have to add AddMaskRecursive(). Plus we'd
   have to add a RemoveRecursive() as well.

2. With Watcher.SetRecursive() like in #339 it's not possible to add
   some paths recursively and others non-recursively, which may be
   useful in some cases. Also, it makes it a bit easier to accept user
   input; in the CLI or config you can set "dir/..." and just pass that
   as-is to fsnotify, without applications having to write special code.

For other watchers it will return ErrRecursionUnsupported for now;
Windows support is already mostly finished in #339, and kqueue can be
added in much the same way as inotify in a future PR.

I also moved all test helpers to helper_test.go, and added a bunch of
"shell-like" functions so you're not forever typing error checks and
filepath.Join(). The new "eventCollector" is also useful in tests to
conveniently collect a slice of events.

TODO:

- Also support recursion in Remove(), and deal with paths added with
  "...". I just updated the documentation but didn't actually implement
  anything.

- A few test cases don't seem quite right; want to get #470 merged first
  as it really confuses things.

- Maybe think of a few more test cases.

[1]: #339 (comment)
arp242 added a commit that referenced this pull request Aug 6, 2022
This adds a recursive watcher for inotify; per my suggestion in [1] it
uses the "/..." syntax in the path to indicate recursive watches,
similar to how Go tools work:

	w, _ := fsnotify.NewWatcher()
	w.Add("some/dir/...")

This will watch "some/dir" as well as any subdirectories of "some/dir".

The upshot of using a syntax like this is that we can:

1. With AddRecursive(path string) adding new Add* methods would become
   hard; for example AddMask("path", fsnotify.Create) to only get CREATE
   events; we'd then also have to add AddMaskRecursive(). Plus we'd
   have to add a RemoveRecursive() as well.

2. With Watcher.SetRecursive() like in #339 it's not possible to add
   some paths recursively and others non-recursively, which may be
   useful in some cases. Also, it makes it a bit easier to accept user
   input; in the CLI or config you can set "dir/..." and just pass that
   as-is to fsnotify, without applications having to write special code.

For other watchers it will return ErrRecursionUnsupported for now;
Windows support is already mostly finished in #339, and kqueue can be
added in much the same way as inotify in a future PR.

I also moved all test helpers to helper_test.go, and added a bunch of
"shell-like" functions so you're not forever typing error checks and
filepath.Join(). The new "eventCollector" is also useful in tests to
conveniently collect a slice of events.

TODO:

- Also support recursion in Remove(), and deal with paths added with
  "...". I just updated the documentation but didn't actually implement
  anything.

- A few test cases don't seem quite right; want to get #470 merged first
  as it really confuses things.

- Maybe think of a few more test cases.

[1]: #339 (comment)
arp242 added a commit that referenced this pull request Aug 6, 2022
This adds a recursive watcher for inotify; per my suggestion in [1] it
uses the "/..." syntax in the path to indicate recursive watches,
similar to how Go tools work:

	w, _ := fsnotify.NewWatcher()
	w.Add("some/dir/...")

This will watch "some/dir" as well as any subdirectories of "some/dir".

The upshot of using a syntax like this is that we can:

1. With AddRecursive(path string) adding new Add* methods would become
   hard; for example AddMask("path", fsnotify.Create) to only get CREATE
   events; we'd then also have to add AddMaskRecursive(). Plus we'd
   have to add a RemoveRecursive() as well.

2. With Watcher.SetRecursive() like in #339 it's not possible to add
   some paths recursively and others non-recursively, which may be
   useful in some cases. Also, it makes it a bit easier to accept user
   input; in the CLI or config you can set "dir/..." and just pass that
   as-is to fsnotify, without applications having to write special code.

For other watchers it will return ErrRecursionUnsupported for now;
Windows support is already mostly finished in #339, and kqueue can be
added in much the same way as inotify in a future PR.

I also moved all test helpers to helper_test.go, and added a bunch of
"shell-like" functions so you're not forever typing error checks and
filepath.Join(). The new "eventCollector" is also useful in tests to
conveniently collect a slice of events.

TODO:

- Also support recursion in Remove(), and deal with paths added with
  "...". I just updated the documentation but didn't actually implement
  anything.

- A few test cases don't seem quite right; want to get #470 merged first
  as it really confuses things.

- Maybe think of a few more test cases.

[1]: #339 (comment)
@abursavich
Copy link

The ignoreLinux function showed up in a profile using 34% of the cpu time for a program I needed to be really efficient. When I came to track down what it was doing, I found this PR instead. Thanks!

@shogo82148 shogo82148 mentioned this pull request Mar 6, 2024
25 tasks
shogo82148 added a commit to shogo82148/fsnotify that referenced this pull request Mar 6, 2024
port of fsnotify/fsnotify#470

This is quite an odd check, leading to an inconsistent event stream,
which also doesn't match what other platforms do. If you do a "CREATE +
MODIFY + REMOVE" in quick succession then you probably *want* all three
events. If you don't want to operate on non-existing files, then you can
check this in your application code.

You need to do that already, since this check is far from reliable. In
the time between this check and the application code doing something
with an event the file may have been deleted already.

I looked a bit at the history of this, and looks like it was added in
2013 with cc2c34e; issue 36 refers to this issue on the old repo, which
mentions it fixes a memory leak: howeyc/fsnotify#36

I can't reproduce that at all; using the CLI from #463 modified to print
the memory and running:

	for i in $(seq 0 10000); { touch $i; rm $i }

Memory stays at about 100/110K in both the current main branch and this.

So I think it should be safe to remove.
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.

None yet

2 participants