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

Implement kqueue-based FileWatcher for MacOS #7

Merged
merged 3 commits into from Sep 20, 2022
Merged

Conversation

kentonv
Copy link
Member

@kentonv kentonv commented Sep 20, 2022

WARNING: THE LAST COMMIT WAS CODED BLIND. I don't have a Mac. If someone could kindly try it out and fix my syntax errors, that would be greatly appreciated!

Assuming it works, you should find that when running workerd serve --watch, the process restarts itself (and logs some messages about this) whenever the input config changes (including any files imported/embedded by the config) or the binary itself changes. It should delay for half a second after the change before actually restarting. If any more file changes are detected in that time, the half-second timeout resets, so if you continuously modify a file then workerd should not restart until you stop modifying it. Again, the text workerd logs to the console should be enough to tell you if it's working.

Copy link
Collaborator

@dom96 dom96 left a comment

Choose a reason for hiding this comment

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

Only two compilation errors, nice.

void watchFd(kj::AutoCloseFd fd) {
struct kevent change;
memset(&change, 0, sizeof(change));
change.ident = fd;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
change.ident = fd;
change.ident = fd.get();

change.ident = fd;
change.filter = EVFILT_VNODE;
change.flags = EV_ADD;
change.fflags = NOTE_WRITE | NOTE_EXTEND | NOTE_DELETE | NODE_RENAME;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
change.fflags = NOTE_WRITE | NOTE_EXTEND | NOTE_DELETE | NODE_RENAME;
change.fflags = NOTE_WRITE | NOTE_EXTEND | NOTE_DELETE | NOTE_RENAME;

@dom96
Copy link
Collaborator

dom96 commented Sep 20, 2022

As for runtime:

➜ ./bazel-bin/src/workerd/server/workerd serve my-config.capnp --watch
Noticed configuration change, reloading shortly...

It notices changes to both my capnp config and the embedded .js file. But then the server locks up (doesn't respond to requests) and I guess it should eventually output a message stating that it successfully reloaded.

memset(&change, 0, sizeof(change));
change.ident = fd;
change.filter = EVFILT_VNODE;
change.flags = EV_ADD;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Found the issue, you want this here:

Suggested change
change.flags = EV_ADD;
change.flags = EV_ADD | EV_ONESHOT;

Then it works perfectly 🎉

Copy link
Member Author

Choose a reason for hiding this comment

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

I think that will break the mechanism that watches for additional changes within 500ms. I think we actually want EV_CLEAR instead of EV_ONESHOT, can you try that?

The kqueue implementation will benefit from using the already-open FD.
This logic will be common to all platforms so it really shouldn't live inside FileWatcher. It's also much cleaner using coroutines, yay.
@kentonv
Copy link
Member Author

kentonv commented Sep 20, 2022

(just a rebase, now making changes)

@kentonv
Copy link
Member Author

kentonv commented Sep 20, 2022

Updated. I also realized that setting close-on-exec was really important here (since we exec() a new process on change) so added that. This has also been rebased on master so has all the other macos fixes. @dom96 mind testing again?

// Class which uses inotify to watch a set of files and alert when they change.
//
// This version uses kqueue to watch for changes in files. kqueue typically doesn't scale well
// to watching whole directory trees, since it must keep a file descriptor opne for each watched
Copy link
Member

@jasnell jasnell Sep 20, 2022

Choose a reason for hiding this comment

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

Suggested change
// to watching whole directory trees, since it must keep a file descriptor opne for each watched
// to watching whole directory trees, since it must keep a file descriptor open for each watched

Just a nit, feel free to ignore

Copy link
Member Author

Choose a reason for hiding this comment

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

GitHub at least allows me to click "commit suggestion" but what I really want it to offer is "apply fixup to source commit", oh well.

@dom96
Copy link
Collaborator

dom96 commented Sep 20, 2022

Re-tested. Works well :)

@kentonv kentonv merged commit b0a0e4e into main Sep 20, 2022
@kentonv kentonv deleted the kenton/kqueue-watch branch September 20, 2022 20:32
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

3 participants