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

Speed up editor detection on Windows #2711

Closed
wants to merge 6 commits into from

Conversation

levrik
Copy link
Contributor

@levrik levrik commented Jul 2, 2017

Follow up to #2552

We could improve that by launching a PowerShell at the beginning in the background and just pipe the commands in then. This would require to switch to a Promise/callback-based implementation of the whole feature. I would pick that up in a second PR later on if you're okay with it 🙂

Time measurement for getting process list (on my machine): ~300ms

One question: Should we launch the PowerShell on the first click in the error overlay (current implementation) or directly on server start (first click would be faster already then)?

@levrik levrik changed the title Speed up editor detection on Windows on subsequent clicks [WIP] Speed up editor detection on Windows on subsequent clicks Jul 2, 2017
@levrik levrik closed this Jul 2, 2017
@levrik levrik reopened this Jul 2, 2017
@levrik levrik force-pushed the speed-up-editor-detection-win branch 2 times, most recently from e8f2be6 to e0fefca Compare July 2, 2017 16:24
@gaearon
Copy link
Contributor

gaearon commented Jul 2, 2017

It's fine to do on start if it's not blocking the first compilation.

@levrik
Copy link
Contributor Author

levrik commented Jul 2, 2017

@gaearon Can you give me some hint where to put that best?

@gaearon
Copy link
Contributor

gaearon commented Jul 2, 2017

In success callback of start.js maybe?

@levrik levrik force-pushed the speed-up-editor-detection-win branch from 5a86215 to 5add09c Compare July 2, 2017 17:00
@levrik levrik changed the title [WIP] Speed up editor detection on Windows on subsequent clicks [WIP] Speed up editor detection on Windows Jul 2, 2017
@levrik levrik changed the title [WIP] Speed up editor detection on Windows Speed up editor detection on Windows Jul 2, 2017
@levrik levrik force-pushed the speed-up-editor-detection-win branch 5 times, most recently from 35e7f29 to 30b2293 Compare July 2, 2017 17:14
before ~600ms
after ~300ms
@levrik levrik force-pushed the speed-up-editor-detection-win branch from 30b2293 to cd28840 Compare July 2, 2017 17:17
@levrik
Copy link
Contributor Author

levrik commented Jul 2, 2017

@gaearon Ready for review.

@@ -85,6 +85,12 @@ choosePort(HOST, DEFAULT_PORT)
}
console.log(chalk.cyan('Starting the development server...\n'));
openBrowser(urls.localUrlForBrowser);
if (process.platform === 'win32') {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this would still block the first compilation, no? It would be nice to check this (e.g. by artificially putting an infinite loop into the launching code). Perhaps setTimeout would help?

Copy link
Contributor Author

@levrik levrik Jul 2, 2017

Choose a reason for hiding this comment

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

Just tested the time overhead:

console.time('start');
if (process.platform === 'win32') {
  const {
    launchPowerShellAgent,
  } = require('react-dev-utils/launchEditor');
  launchPowerShellAgent();
  console.timeEnd('start');
}

Output was start: 4.349ms

But, yes, it would still "block" the first compilation.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, I guess the difference is smaller because we're not actually waiting for process output?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, right. We're just waiting for the process to gets created.

@levrik
Copy link
Contributor Author

levrik commented Jul 29, 2017

@gaearon Friendly ping 🙂

@gaearon
Copy link
Contributor

gaearon commented Jul 30, 2017

I'm not very happy with win32-specific code in start script. It could confuse somebody who ejects. Can we do this in some other way? For example, maybe we could start it lazily whenever the launch editor middleware is created for the first time. Then it would stay an implementation detail without leaking into the script code.

Copy link
Contributor

@gaearon gaearon left a comment

Choose a reason for hiding this comment

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

Let's make this part of the middleware code, and not add specific calls to start.js.

@levrik
Copy link
Contributor Author

levrik commented Jul 30, 2017

@gaearon Okay. Moved it into middleware.js. Besides that the PowerShell agent now only gets started if REACT_EDITOR is not set.

@@ -11,6 +11,11 @@
const { launchEditor } = require('react-dev-utils/launchEditor');

module.exports = function createLaunchEditorMiddleware() {
if (process.platform === 'win32' && !process.env.REACT_EDITOR) {
const { launchPowerShellAgent } = require('react-dev-utils/launchEditor');
launchPowerShellAgent();
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this ever fail?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fails silent if powershell.exe was not found.

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's call it tryLaunchPowerShellAgent to make it clear it's always safe to call.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Or wait. Just tested it again. It seems to break the display of the information about the editor integration if powershell.exe is not found. I look into that :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay. Fixed.

@levrik levrik force-pushed the speed-up-editor-detection-win branch from b46e366 to 5785eaf Compare July 30, 2017 17:37
@gaearon
Copy link
Contributor

gaearon commented Jul 30, 2017

I'll try to review next week. Please ping me on Wednesday.

@levrik
Copy link
Contributor Author

levrik commented Aug 9, 2017

@gaearon Friendly Wednesday ping.

Just realized that you meant the last Wednesday und not this. Somehow got confused there. Sorry.

return new Promise(resolve => {
this.on('resolve', data => {
resolve(data);
this.removeAllListeners('resolve');
Copy link
Contributor

Choose a reason for hiding this comment

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

Are there any possible race conditions here? What if we call invoke twice before it resolves? Will both be resolved correctly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Uhm. I will test that next weekend 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed 🙂

@gaearon
Copy link
Contributor

gaearon commented Sep 6, 2017

@levrik Friendly ping back :-)

@levrik
Copy link
Contributor Author

levrik commented Sep 7, 2017

@gaearon Sorry, had a busy week and forgot about this.
Just checked and found out that the current implementation has serious issues for cases like you described (or rather the implementation was a bit shitty).
Working on a better implementation now.

@levrik levrik force-pushed the speed-up-editor-detection-win branch from 2e0b738 to 2a0560b Compare September 7, 2017 20:14
@levrik levrik force-pushed the speed-up-editor-detection-win branch from 2a0560b to 1a7907f Compare September 7, 2017 20:17
@gaearon
Copy link
Contributor

gaearon commented Sep 8, 2017

Is this ready for another review?

@levrik
Copy link
Contributor Author

levrik commented Sep 8, 2017

@gaearon Yes. Totally!
The issues with the response-mapping are resolved.

const os = require('os');
const chalk = require('chalk');
const shellQuote = require('shell-quote');

// Inspired by https://github.com/rannn505/node-powershell
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason we're not just using it?

Copy link
Contributor Author

@levrik levrik Sep 8, 2017

Choose a reason for hiding this comment

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

In that module you have an method addCommand and an method invoke.
With addCommand you can add one to many commands and execute them with invoke at once, getting the output of all commands. I wanted a clear connection between a command and its result.

Copy link
Contributor

@Timer Timer Sep 8, 2017

Choose a reason for hiding this comment

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

Maybe we could send a pull request to the module, adding an execute shortcut which calls addCommand and invoke?


invoke(cmd) {
return new Promise(resolve => {
const eventName = 'resolve' + ++this._resolveCounter;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you try without using EventEmitter? I find code built on events (especially with dynamic names) easy to mess up by accidentally triggering or listening to a wrong event. I would prefer plain callback lists.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure.

@levrik
Copy link
Contributor Author

levrik commented Jan 15, 2018

@gaearon Sorry that nothing happened here anymore. Quick question: Would you like to get these improvements in? I'm not sure if it's worth it.

@gaearon gaearon added this to the 2.0.0 milestone Jan 15, 2018
@gaearon
Copy link
Contributor

gaearon commented Jan 15, 2018

Yes, totally!

@gaearon gaearon changed the base branch from master to next January 15, 2018 19:17
@levrik
Copy link
Contributor Author

levrik commented Jan 15, 2018

Closed in favor of #3808

@levrik levrik closed this Jan 15, 2018
@lock lock bot locked and limited conversation to collaborators Jan 20, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants