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

use FSEventStreamSetDispatchQueue instead of deprecated FSEventStreamScheduleWithRunLoop #62

Merged
merged 5 commits into from
May 14, 2024

Conversation

emanuel-skrenkovic
Copy link
Contributor

Hello!

FSEventStreamScheduleWithRunLoop is deprecated and triggers compile warnings so I basically made this change for myself to get rid of the warning.

Wanted to open the create the PR in case this is actually a useful change to have. Feel free to close the PR if the change is not needed.

What does this pull request do?

Replaces the deprecated FSEventStreamScheduleWithRunLoop with the suggested FSEventStreamSetDispatchQueue.
Also removes the run loop part, as FSEventStreamSetDispatchQueue handles it itself using a separate, hidden thread.
The behavior remains the same - calling Start is non-blocking.

Helpful discussion I found on the web:
https://www.spinics.net/lists/git/msg452085.html

For FSEventStreamScheduleWithRunLoop the docs say:
Introduced in macOS 10.5 and deprecated in macOS 13.0

FSEventStreamSetDispatchQueue the docs say:
Available on macOS 10.6 and later

Seems like macOS 10.5 gets shafted by this change but only that version.

Where should the reviewer start?

wrap.go

The test TestBasicExample tests that the code actually works, but all the tests here are very basic, and frankly, I don't have enough understanding of this to prove this doesn't break something.

https://github.com/docker/compose has a direct dependency on fsevents, and I tried running all their tests using my fsevents code and nothing seemed to break. Not sure that the right code paths were executed though.

How should this be manually tested?

I do not know, to be honest. I just modified the TestBasicExample to create a bunch of files and events seemed to be emitted properly.

Have a nice day!

@arp242
Copy link
Member

arp242 commented May 1, 2024

The test TestBasicExample tests that the code actually works, but all the tests here are very basic, and frankly, I don't have enough understanding of this to prove this doesn't break something.

Yes, this was also my concern with #61, and why I haven't merged that.

Personally what I'd do is copy the tests from fsnotify; the testdata directory has test scripts that can probably be ported fairly easily. They're run with TestScript() and parsed with helpers_test.go. Just need to update things like NewWatcher() with whatever fsevents has for this and then, hopefully, it should work reasonably well without too much effort.

I fixed the CI in #63, so at least that should run again.

@emanuel-skrenkovic

This comment was marked as outdated.

@arp242

This comment was marked as outdated.

@arp242

This comment was marked as outdated.

@emanuel-skrenkovic

This comment was marked as outdated.

@arp242

This comment was marked as outdated.

@arp242

This comment was marked as outdated.

@emanuel-skrenkovic

This comment was marked as outdated.

@emanuel-skrenkovic emanuel-skrenkovic mentioned this pull request May 3, 2024
@emanuel-skrenkovic

This comment was marked as outdated.

@arp242
Copy link
Member

arp242 commented May 7, 2024

Seems like the CI fails because of a race condition in the test; you need to either protect events with a mutex, or return in that goroutine that collects the events before you loop over the events.

Fixes the race condition in the test.
@pbnjay
Copy link
Contributor

pbnjay commented May 14, 2024

This looks good to me, one minor quibble is the addition of DispatchQueueRelease which adds a layer of indirection. Since this PR uses dispatch_queue_create directly I think we can just use dispatch_release directly as well and simplify the code paths. (The other C wrappers do C pointer manipulation so they make sense)

@emanuel-skrenkovic
Copy link
Contributor Author

This looks good to me, one minor quibble is the addition of DispatchQueueRelease which adds a layer of indirection. Since this PR uses dispatch_queue_create directly I think we can just use dispatch_release directly as well and simplify the code paths. (The other C wrappers do C pointer manipulation so they make sense)

Thanks for looking at the code!

The reason I did the indirection is because of types - Golang won't allow me to treat dispatch_queue_t (which is returned from dispatch_queue_create) as dispatch_object_t (which dispatch_release takes in).

Passing the argument in C code allows for implicit type conversion.

I don't have too much experience with cgo so I could be missing something. I would've preferred to avoid indirection if possible, so if there's a way, I'll change it. :)

Tried conversion and ends up in this :(
cannot convert a (variable of type _Ctype_dispatch_queue_t) to type _Ctype_dispatch_object_t

And passing the dispatch_queue_t into dispatch_release ends up with this:
cannot use a (variable of type _Ctype_dispatch_queue_t) as _Ctype_dispatch_object_t value in argument to (_Cfunc_dispatch_release)

@pbnjay
Copy link
Contributor

pbnjay commented May 14, 2024

Aha that makes sense, I missed that. Could wrap the create call for more symmetry but I don’t feel as strongly there.

LGTM!

Copy link
Contributor

@pbnjay pbnjay left a comment

Choose a reason for hiding this comment

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

LGTM

@arp242 arp242 merged commit f73112e into fsnotify:main May 14, 2024
5 checks passed
@arp242
Copy link
Member

arp242 commented May 14, 2024

Thanks! I merged it and tagged v0.2.0

@emanuel-skrenkovic
Copy link
Contributor Author

Thanks for all the help!

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.

3 participants