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

FSEvents watcher #97

Merged
merged 8 commits into from Jun 25, 2017
Merged

FSEvents watcher #97

merged 8 commits into from Jun 25, 2017

Conversation

amasad
Copy link
Owner

@amasad amasad commented May 30, 2017

There seems to be some kind of regression with the node watcher in MacOS serria:

This adds another watcher that consumers can use for MacOS.

@amasad amasad requested a review from stefanpenner May 30, 2017 02:13
@amasad
Copy link
Owner Author

amasad commented May 30, 2017

/cc @ro-savage @gaearon @thisconnect

@amasad amasad changed the title FSEvents watcher [wip] FSEvents watcher May 30, 2017
@amasad
Copy link
Owner Author

amasad commented May 30, 2017

Keep getting unknown from fsevents. Looks like we need to do a bit more ninja moves to handle this. Will pick this up later unless someone else wants to

});
}

function emit(stat) {
Copy link
Contributor

Choose a reason for hiding this comment

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

All the this should be changed to self

Copy link
Collaborator

Choose a reason for hiding this comment

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

^.

Copy link
Owner Author

Choose a reason for hiding this comment

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

yeah sorry fixed locally and didn't update the branch

@ro-savage
Copy link
Contributor

A very quick test using the cra-desktop and fixing up the this / self bug it seemed to watch everything fine and without crashing.

There was an issue with creating files though. If I create a file using SublimeText, fsevents fired a modified event rather than a created event.

{ path: '/Users/Ro/www/create-react-app/test-watch/something.js',
  event: 'modified',
  type: 'file',
  changes: { inode: false, finder: true, access: false, xattrs: true },
  flags: 110848,
  id: 94649282 }

If I create a file with touch fsevent fires a unknown event

{ path: '/Users/Ro/www/create-react-app/test-watch/touch.js',
  event: 'unknown',
  type: 'file',
  changes: { inode: false, finder: false, access: false, xattrs: false },
  flags: 65792,
  id: 94649923 }

Tried both of these a few times, and got the same result each time.

@thisconnect
Copy link

thisconnect commented May 30, 2017

@ro-savage the created/modified event seems to be known, see the comment in fsevent test


FSEventsWatcher.prototype.emitEvent = function(type, file) {
var self = this;
console.log('here');
Copy link
Collaborator

Choose a reason for hiding this comment

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

^

this.watcher.stop();
this.removeAllListeners();
if (typeof callback === 'function') {
setImmediate(callback.bind(null, null, true));
Copy link
Collaborator

Choose a reason for hiding this comment

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

curious why setImmediate over process.nextTick ?

Copy link
Owner Author

Choose a reason for hiding this comment

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

no reason this can be nextTick

"homepage": "https://github.com/amasad/sane"
"homepage": "https://github.com/amasad/sane",
"optionalDependencies": {
"fsevents": "^1.1.1"
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm nervous to introduce the node-gyp dependency here. Although it is an optional dependency the ergonomics around failed optionalDependencies is still quite poor for those with funky environments.

On a positive note, it looks like fsevents does seems to do its best to avoid pain here:

One last concern is if the binaries themselves are not stored in the registry, so companies with private registries (for insulation from the outside world) might become unhappy. For this reason, if we proceed I would like to recommend this be at-least a major version bump.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Yeah agreed. I'm really reluctant to do it. But the problem is badd enough that the NodeWatcher is not usable on some machines (including mine).

Copy link
Collaborator

Choose a reason for hiding this comment

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

@amasad if you gotta, mind doing a major version bump? or...

Copy link
Owner Author

Choose a reason for hiding this comment

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

of course

});
}

function emit(stat) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

^.

@amasad
Copy link
Owner Author

amasad commented May 30, 2017

@ro-savage yeah it seems like we need to handle these unknowns on our own. We need to keep a registry of files and deduce what changed. 😕

@gaearon
Copy link

gaearon commented May 30, 2017

Worth taking a look at how Chokidar uses fsevents? It's been working pretty well in webpack (even if it's not at FB scale).

@ro-savage
Copy link
Contributor

ro-savage commented May 31, 2017

Chokidar is doing exactly what @amasad mentioned.

It keeps an object that contains every item tracked and anytime fsevents fires a change/created/unknown event it checks it's registry of items and decided what actually happened.

Feels extreme, but it appears the only way to make sure its correct. So that's Option 1.

Option 2
You could also just fire a modified for all unknowns under the assumption that watchers mainly care if something changed rather that if its created or modified. And recommend people use Chokidar if they'd need to know for sure if something is created or modified.

(I actually have no idea of the implications of having an object with tens of thousands of properties in node, maybe it doesn't cause any issues with speed/memory)

Option 3
Change Jest and React-Native to use Chokidar and allow sane to keep doing what it does.

What's your thoughts @amasad ?

@amasad
Copy link
Owner Author

amasad commented May 31, 2017

Option 1

Not extreme at all. We already do that for the node watcher. The reason Sane exists (and the reason for the name) is because native node watcher was garbage (it's still is I guess). See this.

Option 2

That's a non-starter -- the whole point of Sane is to paper over multiple watcher backends with the same API so that consumers can slide them in and out as they please.

Option 3

More than happy to deprecate if the major consumers think they can live without it /cc @cpojer, @stefanpenner, @gaearon et al.

My guess is that there is still value in the abstraction this provide so that you can switch between the different watchers depending on the platform and/or capabilities.

@gaearon
Copy link

gaearon commented May 31, 2017

@amasad Do you think you could find the time to finish up "option 1"?

@amasad
Copy link
Owner Author

amasad commented May 31, 2017

@gaearon yeah, most likely do it this weekend.

@gaearon
Copy link

gaearon commented Jun 7, 2017

Friendly ping 😄

Do you think you could finish this, or maybe somebody else could help?
It would mean a lot to our users who are still struggling with those issues.

@amasad
Copy link
Owner Author

amasad commented Jun 7, 2017

Yes made some progress. Ill cleanup, send an update on progress later today.

@amasad
Copy link
Owner Author

amasad commented Jun 13, 2017

Ok this is passing tests and looks like its working well. I'll wait for comments then merge and release an alpha. Sorry for the delay @gaearon.

@amasad amasad changed the title [wip] FSEvents watcher FSEvents watcher Jun 13, 2017
@gaearon
Copy link

gaearon commented Jun 13, 2017

No worries, thank you so much for the followup! Fingers crossed.

@thisconnect
Copy link

thisconnect commented Jun 17, 2017

Is it correct that we have to modify jest on this line https://github.com/facebook/jest/blob/79eed2558402d660f914b47833658625399bbaff/packages/jest-haste-map/src/index.js#L569-L571
to test this sane version?

@thisconnect
Copy link

thisconnect commented Jun 17, 2017

Ok success, tested facebook/create-react-app#2393 with repo https://github.com/thisconnect/cra-desktop

rm -rf node_modules/sane
rm -rf node_modules/jest-haste-map/node_modules/sane
npm i amasad/sane#fsevents
vi node_modules/jest-haste-map/build/index.js
# changes line 571
# from ": sane.NodeWatcher;"
# to "sane.FSEventsWatcher;"
npm t 
# WORKS with no error!
  • no error
  • changing a file in node_modules seems to re-trigger the tests
  • the tests in src work

testing the error one more time

rm -rf node_modules && npm i && npm t
# old error works too :)

@ro-savage
Copy link
Contributor

ro-savage commented Jun 17, 2017

Sorry been on holidays.

Tested it with a Create React App where I just installed a bunch of large npm packages. Came out at 1200+ packages and approximately 50,000 files.

Died on old sane. Worked fine on this branch.

I'd say go ahead and release.

@MylesBorins
Copy link

hey all... is there something that core can do to hell with this regression? we are getting some new test infra for osx soon, which should hell find regressions.

@gaearon
Copy link

gaearon commented Jun 22, 2017

Seems to work in my testing! Is there anything else holding this back?

@thisconnect
Copy link

@ro-savage and @gaearon did you patch jest-hastle-maps as in #97 (comment)

or was sane a drop in replacement?

@gaearon
Copy link

gaearon commented Jun 22, 2017

I did patch that file, yes.

@amasad
Copy link
Owner Author

amasad commented Jun 23, 2017

@gaearon I'm OOO. But I'll find time for the release. Sorry bout the hold up.

@MylesBorins thanks for the offer. I think the most important thing is to test against really large directories. This is vague in my memory but my understanding is that I you look at watchman and the npm module fsevents does a better job at reusing watches (and even multiplexing I the case of watchman) where is native node watcher is resource hungry.

@amasad amasad merged commit 803407c into master Jun 25, 2017
@amasad amasad deleted the fsevents branch June 25, 2017 00:28
@amasad
Copy link
Owner Author

amasad commented Jun 25, 2017

Merged. And sent a PR to jest. jestjs/jest#3902

SimenB pushed a commit to SimenB/jest that referenced this pull request Jun 26, 2017
This is to fix regressions with the NodeWatcher on macOS.
More info here: amasad/sane#97
cpojer pushed a commit to jestjs/jest that referenced this pull request Jun 27, 2017
This is to fix regressions with the NodeWatcher on macOS.
More info here: amasad/sane#97
tushardhole pushed a commit to tushardhole/jest that referenced this pull request Aug 21, 2017
This is to fix regressions with the NodeWatcher on macOS.
More info here: amasad/sane#97
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

6 participants