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: add recursive watcher #472

Merged
merged 1 commit into from May 1, 2024
Merged

inotify: add recursive watcher #472

merged 1 commit into from May 1, 2024

Conversation

arp242
Copy link
Member

@arp242 arp242 commented Jul 25, 2022

This adds a recursive watcher for inotify.

Updates: #18

arp242 added a commit that referenced this pull request Jul 30, 2022
This rewrites quite a lot of tests to be much more easily readable.

While working on #472 I wanted to check "how do renames behave now?",
and found this quite hard as most test cases were >90% "plumbing", and
seeing "what file operations does this do?" and "what events do we get?"
was not very easy.

So refactor the lot, based on some work I did in #472:

- Add a bunch of "shell-like" helper functions so you're not forever
  typing error checks, filepath.Join(), and eventSeparator(). Just
  touch(t, tmp, "file") will create a file in tmp.

- Add eventCollector type which will collect all events in in a slice,
  replacing the previous "counter". This also ensures that the Watcher
  is closed within a second (this removes a lot of duplicate code).

  This is also much more precise than merely counting events; before
  random events could get emitted but if you weren't counting those then
  you'd never know.

  Downside is that some tests are a bit more flaky now as some
  behaviours are not always consistent in various edge cases; these are
  pre-existing bugs.

- Add Events (plural) type (only for tests), and helper function to
  create this from a string like:

      REMOVE  /link
      CREATE  /link
      WRITE   /link

  Which makes seeing which events are received, diffing them, etc. much
  easier.

- Add Parallel() for most tests; reduces runtime on my system from ~12
  seconds to ~6 seconds.

All in all it reduces the integrations_test.go from 1279 lines to 405
lines and it's quite easy to see which events are expected for which
operations, which should make things a lot easier going forward.
@arp242 arp242 mentioned this pull request Jul 30, 2022
fsnotify.go Outdated Show resolved Hide resolved
Copy link
Member

@horahoradev horahoradev left a comment

Choose a reason for hiding this comment

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

LGTM aside from my comments and the remaining TODOs. If you address the feedback and TODOs, then I'll approve.

inotify.go Outdated Show resolved Hide resolved
inotify.go Outdated Show resolved Hide resolved
arp242 added a commit that referenced this pull request Jul 31, 2022
Rewrite tests

This rewrites quite a lot of tests to be much more easily readable.

While working on #472 I wanted to check "how do renames behave now?",
and found this quite hard as most test cases were >90% "plumbing", and
seeing "what file operations does this do?" and "what events do we get?"
was not very easy.

So refactor the lot, based on some work I did in #472:

- Add a bunch of "shell-like" helper functions so you're not forever
  typing error checks, filepath.Join(), and eventSeparator(). Just
  touch(t, tmp, "file") will create a file in tmp.

- Add eventCollector type which will collect all events in in a slice,
  replacing the previous "counter". This also ensures that the Watcher
  is closed within a second (this removes a lot of duplicate code).

  This is also much more precise than merely counting events; before
  random events could get emitted but if you weren't counting those then
  you'd never know.

  Downside is that some tests are a bit more flaky now as some
  behaviours are not always consistent in various edge cases; these are
  pre-existing bugs.

- Add Events (plural) type (only for tests), and helper function to
  create this from a string like:

      REMOVE  /link
      CREATE  /link
      WRITE   /link

  Which makes seeing which events are received, diffing them, etc. much
  easier.

- Add Parallel() for most tests; reduces runtime on my system from ~12
  seconds to ~6 seconds.

All in all it reduces the integrations_test.go from 1279 lines to 405
lines and it's quite easy to see which events are expected for which
operations, which should make things a lot easier going forward.
@arp242 arp242 marked this pull request as draft August 1, 2022 21:48
@arp242 arp242 force-pushed the inotify-recurse branch 3 times, most recently from a21593f to 1a30f16 Compare August 6, 2022 17:56
@fsnotify fsnotify deleted a comment from solarknight Nov 17, 2022
arp242 added a commit that referenced this pull request Dec 20, 2022
Create a new watcher type to keep track of the watches instead of
keeping two maps on the Watcher and accessing these directly.

This makes the bookkeeping a bit easier to follow, and we no longer need
to worry about locking map access as the watcher type takes care of that
now.

Came up in #472 where I want to keep track if a path was added
recursively, and this makes that a bit easier.

Also seems a bit faster:

	BenchmarkWatch-2          903709              7122 ns/op             194 B/op          3 allocs/op
	BenchmarkWatch-2          923980              6322 ns/op             196 B/op          3 allocs/op

Although that benchmark is very simply and only tests one code path;
just want to make sure it's not a horrible regression.
arp242 added a commit that referenced this pull request Dec 20, 2022
Create a new watcher type to keep track of the watches instead of
keeping two maps on the Watcher and accessing these directly.

This makes the bookkeeping a bit easier to follow, and we no longer need
to worry about locking map access as the watcher type takes care of that
now.

Came up in #472 where I want to keep track if a path was added
recursively, and this makes that a bit easier.

Also seems a bit faster:

	BenchmarkWatch-2          903709              7122 ns/op             194 B/op          3 allocs/op
	BenchmarkWatch-2          923980              6322 ns/op             196 B/op          3 allocs/op

Although that benchmark is very simply and only tests one code path;
just want to make sure it's not a horrible regression.
arp242 added a commit that referenced this pull request Dec 20, 2022
Create a new watcher type to keep track of the watches instead of
keeping two maps on the Watcher and accessing these directly.

This makes the bookkeeping a bit easier to follow, and we no longer need
to worry about locking map access as the watcher type takes care of that
now.

Came up in #472 where I want to keep track if a path was added
recursively, and this makes that a bit easier.

Also seems a bit faster:

	BenchmarkWatch-2          903709              7122 ns/op             194 B/op          3 allocs/op
	BenchmarkWatch-2          923980              6322 ns/op             196 B/op          3 allocs/op

Although that benchmark is very simply and only tests one code path;
just want to make sure it's not a horrible regression.
arp242 added a commit that referenced this pull request Dec 21, 2022
Create a new watcher type to keep track of the watches instead of
keeping two maps on the Watcher and accessing these directly.

This makes the bookkeeping a bit easier to follow, and we no longer need
to worry about locking map access as the watcher type takes care of that
now.

Came up in #472 where I want to keep track if a path was added
recursively, and this makes that a bit easier.

Also seems a bit faster:

	BenchmarkWatch-2          903709              7122 ns/op             194 B/op          3 allocs/op
	BenchmarkWatch-2          923980              6322 ns/op             196 B/op          3 allocs/op

Although that benchmark is very simply and only tests one code path;
just want to make sure it's not a horrible regression.
arp242 added a commit that referenced this pull request Dec 21, 2022
Create a new watches type to keep track of the watches instead of
keeping two maps on the Watcher and accessing these directly.

This makes the bookkeeping a bit easier to follow, and we no longer need
to worry about locking map access as the watcher type takes care of that
now.

Came up in #472 where I want to keep track if a path was added
recursively, and this makes that a bit easier.

Also seems a bit faster:

	BenchmarkWatch-2          903709              7122 ns/op             194 B/op          3 allocs/op
	BenchmarkWatch-2          923980              6322 ns/op             196 B/op          3 allocs/op

Although that benchmark is very simply and only tests one code path;
just want to make sure it's not a horrible regression.
arp242 added a commit that referenced this pull request Dec 22, 2022
Create a new watches type to keep track of the watches instead of
keeping two maps on the Watcher and accessing these directly.

This makes the bookkeeping a bit easier to follow, and we no longer need
to worry about locking map access as the watcher type takes care of that
now.

Came up in #472 where I want to keep track if a path was added
recursively, and this makes that a bit easier.

Also seems a bit faster:

	BenchmarkWatch-2          903709              7122 ns/op             194 B/op          3 allocs/op
	BenchmarkWatch-2          923980              6322 ns/op             196 B/op          3 allocs/op

Although that benchmark is very simply and only tests one code path;
just want to make sure it's not a horrible regression.
arp242 added a commit that referenced this pull request Jan 12, 2023
Create a new watches type to keep track of the watches instead of
keeping two maps on the Watcher and accessing these directly.

This makes the bookkeeping a bit easier to follow, and we no longer need
to worry about locking map access as the watcher type takes care of that
now.

Came up in #472 where I want to keep track if a path was added
recursively, and this makes that a bit easier.

Also seems a bit faster:

	BenchmarkWatch-2          903709              7122 ns/op             194 B/op          3 allocs/op
	BenchmarkWatch-2          923980              6322 ns/op             196 B/op          3 allocs/op

Although that benchmark is very simply and only tests one code path;
just want to make sure it's not a horrible regression.
arp242 added a commit that referenced this pull request Jan 14, 2023
Create a new watches type to keep track of the watches instead of
keeping two maps on the Watcher and accessing these directly.

This makes the bookkeeping a bit easier to follow, and we no longer need
to worry about locking map access as the watcher type takes care of that
now.

Came up in #472 where I want to keep track if a path was added
recursively, and this makes that a bit easier.

Also seems a bit faster:

	BenchmarkWatch-2          903709              7122 ns/op             194 B/op          3 allocs/op
	BenchmarkWatch-2          923980              6322 ns/op             196 B/op          3 allocs/op

Although that benchmark is very simply and only tests one code path;
just want to make sure it's not a horrible regression.
@arp242 arp242 force-pushed the inotify-recurse branch 4 times, most recently from d3727c3 to f4c00e5 Compare May 1, 2024 20:10
This adds a recursive watcher for inotify.
@arp242 arp242 marked this pull request as ready for review May 1, 2024 20:13
@arp242 arp242 merged commit a618f07 into main May 1, 2024
18 checks passed
@arp242 arp242 deleted the inotify-recurse branch May 1, 2024 20:24
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