-
Notifications
You must be signed in to change notification settings - Fork 30k
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
child_process spawn, execFile, etc. is tremendously slower at Windows and takes minutes #21632
Comments
Unable to reproduce the issue. Here is my output on Windows 10 x64 using your script: C:\21632>npm run test-child-spawn-nodejs
> @ test-child-spawn-nodejs C:\21632
> node main.js
Message received in 1766.736999 ms
trvsapjiac
Message received in 15.665841 ms
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
main.js
package.json
nothing added to commit but untracked files present (use "git add" to track) It takes ~1.7 sec in total. |
@trvsapjiac Which node version are you using? I will try to perform some more tests and gather some more data about the environment. |
v10.5.0 |
Okay, we performed some other tests and it seems that this tremendous slowdown does only happen if we execute Furthermore we use NPM behind a corporate proxy and have enabled NPM's proxy and https-proxy and utilise the So we created another NPM-only test script und sniffed all traffic with Fiddler, here are the results:
So the network isn't the problem, but maybe the usage of a proxy creates a wrong state in npm, which causes this tremendous delay. The new npm-only test-script const { execFile } = require('child_process');
const precise = require('precise');
const timer = precise();
// Node does not support PATHEXT on Windows
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
timer.start();
execFile(npmCmd, ['whoami'], (error, stdout, stderr) => {
timer.stop();
console.log('Message received in', timer.diff() / 1000000, 'ms');
if (error) {
console.error(error);
} else {
console.log(stdout);
}
const timer2 = precise();
timer2.start();
execFile(npmCmd, ['owner', 'ls'], (error, stdout, stderr) => {
timer2.stop();
console.log('Message received in', timer2.diff() / 1000000, 'ms');
if (error) {
console.error(error);
} else {
console.log(stdout);
}
});
}); The CLI output (on Windows 10): C:\eplatform\git-repos\patterns-library>npm run test-child-spawn-nodejs
> @axa-ch/patterns-library@2.0.1-beta.160 test-child-spawn-nodejs C:\eplatform\git-repos\patterns-library
> node ./stack/tasks/test-child-spawn-nodejs.js
Message received in 189448.449313 ms
user-name
Message received in 189201.805259 ms
andyogo <andy.782542@gmail.com>
axa-ch-user <aem@axa.ch>
lucamele <lucamele1@hotmail.com>
thedadi <difada1@hotmail.com> Fiddler Log of This is a Tunnel. Status: CLOSED, Raw Bytes Out: 722; In: 6'596
The selected session is a HTTP CONNECT Tunnel. This tunnel enables a client to send raw traffic (e.g. HTTPS-encrypted streams or WebSocket messages) through a HTTP Proxy Server (like Fiddler).
To enable Fiddler's HTTPS-decryption feature and view decrypted traffic, click Tools > Fiddler Options > HTTPS.
Request Count: 1
Bytes Sent: 204 (headers:204; body:0)
Bytes Received: 115 (headers:115; body:0)
Tunnel Sent: 722
Tunnel Received: 6'596
ACTUAL PERFORMANCE
--------------
ClientConnected: 12:49:57.827
ClientBeginRequest: 12:49:57.830
GotRequestHeaders: 12:49:57.830
ClientDoneRequest: 12:49:57.830
Determine Gateway: 0ms
DNS Lookup: 0ms
TCP/IP Connect: 1ms
HTTPS Handshake: 0ms
ServerConnected: 12:49:57.833
FiddlerBeginRequest: 12:49:57.833
ServerGotRequest: 12:49:57.833
ServerBeginResponse: 12:49:57.840
GotResponseHeaders: 12:49:57.840
ServerDoneResponse: 12:49:58.775
ClientBeginResponse: 12:49:58.775
ClientDoneResponse: 12:49:58.775
Overall Elapsed: 0:00:00.945
RESPONSE BYTES (by Content-Type)
--------------
~headers~: 115
ESTIMATED WORLDWIDE PERFORMANCE
--------------
The following are VERY rough estimates of download times when hitting servers based in Seattle.
US West Coast (Modem - 6KB/sec)
RTT: 0.10s
Elapsed: 0.10s
Japan / Northern Europe (Modem)
RTT: 0.15s
Elapsed: 0.15s
China (Modem)
RTT: 0.45s
Elapsed: 0.45s
US West Coast (DSL - 30KB/sec)
RTT: 0.10s
Elapsed: 0.10s
Japan / Northern Europe (DSL)
RTT: 0.15s
Elapsed: 0.15s
China (DSL)
RTT: 0.45s
Elapsed: 0.45s Fiddler Log of The selected session is a HTTP CONNECT Tunnel. This tunnel enables a client to send raw traffic (e.g. HTTPS-encrypted streams or WebSocket messages) through a HTTP Proxy Server (like Fiddler).
To enable Fiddler's HTTPS-decryption feature and view decrypted traffic, click Tools > Fiddler Options > HTTPS.
Request Count: 1
Bytes Sent: 206 (headers:206; body:0)
Bytes Received: 116 (headers:116; body:0)
Tunnel Sent: 742
Tunnel Received: 83'019
ACTUAL PERFORMANCE
--------------
ClientConnected: 12:53:05.895
ClientBeginRequest: 12:53:05.899
GotRequestHeaders: 12:53:05.899
ClientDoneRequest: 12:53:05.899
Determine Gateway: 0ms
DNS Lookup: 0ms
TCP/IP Connect: 1ms
HTTPS Handshake: 0ms
ServerConnected: 12:53:05.902
FiddlerBeginRequest: 12:53:05.902
ServerGotRequest: 12:53:05.902
ServerBeginResponse: 12:53:05.907
GotResponseHeaders: 12:53:05.907
ServerDoneResponse: 12:53:07.607
ClientBeginResponse: 12:53:07.607
ClientDoneResponse: 12:53:07.607
Overall Elapsed: 0:00:01.707
RESPONSE BYTES (by Content-Type)
--------------
~headers~: 116
ESTIMATED WORLDWIDE PERFORMANCE
--------------
The following are VERY rough estimates of download times when hitting servers based in Seattle.
US West Coast (Modem - 6KB/sec)
RTT: 0.10s
Elapsed: 0.10s
Japan / Northern Europe (Modem)
RTT: 0.15s
Elapsed: 0.15s
China (Modem)
RTT: 0.45s
Elapsed: 0.45s
US West Coast (DSL - 30KB/sec)
RTT: 0.10s
Elapsed: 0.10s
Japan / Northern Europe (DSL)
RTT: 0.15s
Elapsed: 0.15s
China (DSL)
RTT: 0.45s
Elapsed: 0.45s |
@nodejs/platform-windows |
This looks a lot like an issue with NPM, not Node. @AndyOGo , I think you should report this issue in the npm issue tracker |
@bzoz Please take the time to investigate this issue deeply. Issue at npm: |
Yeah, if it runs ok from CLI then there could be something going on. Some ideas:
|
Thanks for your answer, really good points, will try it asap and share my results here, though probably not until next week. |
@bzoz So either the bugs is in C:\eplatform\git-repos\patterns-library (bugfix/windows-spawn-hangs -> origin) (@axa-ch/patterns-library@2.0.1-beta.160)
λ node .\stack\tasks\test-child-spawn-nodejs.js
Message received in 189201.678317 ms
user-name
Message received in 164.329462 ms
On branch bugfix/windows-spawn-hangs
Your branch is up to date with 'origin/bugfix/windows-spawn-hangs'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
.idea/
patterns-library.iml
nothing added to commit but untracked files present (use "git add" to track) |
Does the slowness occur if spawn/execFile is called with the absolute/relative path to node/deps/uv/src/win/process.c Lines 298 to 447 in 8476053
|
@richardlau // Node does not support PATHEXT on Windows
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm'; |
@richardlau @bzoz const { execFile } = require('child_process');
const precise = require('precise');
const timer = precise();
// Node does not support PATHEXT on Windows
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
timer.start();
execFile(npmCmd, ['whoami'], { 'shell': true },(error, stdout, stderr) => {
timer.stop();
console.log('Message received in', timer.diff() / 1000000, 'ms');
if (error) {
console.error(error);
} else {
console.log(stdout);
}
const timer2 = precise();
timer2.start();
execFile('git', ['status'], (error, stdout, stderr) => {
timer2.stop();
console.log('Message received in', timer2.diff() / 1000000, 'ms');
if (error) {
console.error(error);
} else {
console.log(stdout);
}
}); Shell-output: npm run test-child-spawn-nodejs --verbose
npm info it worked if it ends with ok
npm verb cli [ 'C:\\eplatform\\tools\\node\\node.exe',
npm verb cli 'C:\\eplatform\\tools\\node\\node_modules\\npm\\bin\\npm-cli.js',
npm verb cli 'run',
npm verb cli 'test-child-spawn-nodejs',
npm verb cli '--verbose' ]
npm info using npm@6.1.0
npm info using node@v10.6.0
npm verb run-script [ 'pretest-child-spawn-nodejs',
npm verb run-script 'test-child-spawn-nodejs',
npm verb run-script 'posttest-child-spawn-nodejs' ]
npm info lifecycle @axa-ch/patterns-library@2.0.1-beta.160~pretest-child-spawn-nodejs: @axa-ch/patterns-library@2.0.1-beta.160
npm info lifecycle @axa-ch/patterns-library@2.0.1-beta.160~test-child-spawn-nodejs: @axa-ch/patterns-library@2.0.1-beta.160
> @axa-ch/patterns-library@2.0.1-beta.160 test-child-spawn-nodejs C:\eplatform\git-repos\patterns-library
> node ./stack/tasks/test-child-spawn-nodejs.js
Message received in 189270.100785 ms
user-name
Message received in 183.891797 ms
On branch bugfix/windows-spawn-hangs
Your branch is up to date with 'origin/bugfix/windows-spawn-hangs'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: stack/tasks/test-child-spawn-nodejs.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
.idea/
patterns-library.iml
no changes added to commit (use "git add" and/or "git commit -a")
npm verb lifecycle @axa-ch/patterns-library@2.0.1-beta.160~test-child-spawn-nodejs: unsafe-perm in lifecycle true
npm verb lifecycle @axa-ch/patterns-library@2.0.1-beta.160~test-child-spawn-nodejs: PATH: C:\eplatform\tools\node\node_modules\npm\node_modules\npm-lifecycle\node-gyp-bin;C:\eplatform\git-repos\patterns-library\node_modules\.bin;C:\eplatform\tools\cmder_mini\bin;C:\eplatform\tools\cmder_mini\vendor\conemu-maximus5\ConEmu\Scripts;C:\eplatform\tools\cmder_mini\vendor\conemu-maximus5;C:\eplatform\tools\cmder_mini\vendor\conemu-maximus5\ConEmu;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files\oracle\instantclient\12.2.0.1;C:\Program Files (x86)\oracle\instantclient\12.2.0.1;C:\Program Files (x86)\IBM\Trace Facility\;C:\Program Files (x86)\IBM\Personal Communications\;C:\ProgramData\Oracle\Java\javapath;C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;c:\Sysdat\Tools;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\PTKT;C:\WINDOWS\system32\config\systemprofile\AppData\Local\Microsoft\WindowsApps;C:\Program Files (x86)\ibm\gsk8\lib;C:\Program Files\ibm\gsk8\lib64;C:\PROGRA~1\IBMDSC\SQLLIB\BIN;C:\PROGRA~1\IBMDSC\SQLLIB\FUNCTION;C:\PROGRA~1\IBMDSC\SQLLIB\SAMPLES\REPL;C:\Program Files\IBM\WebSphere MQ\bin64;C:\Program Files\IBM\WebSphere MQ\bin;C:\Users\C193577\AppData\Local\Microsoft\WindowsApps;C:\Program Files\IDM Computer Solutions\UltraEdit\;C:\eplatform\tools\Git\bin;C:\eplatform\tools\maven\3\bin;C:\eplatform\tools\node;C:\eplatform\tools\oc-3.9;;C:\eplatform\tools\Git\usr\bin;C:\eplatform\tools\Git\usr\share\vim\vim74;C:\eplatform\tools\cmder_mini\
npm verb lifecycle @axa-ch/patterns-library@2.0.1-beta.160~test-child-spawn-nodejs: CWD: C:\eplatform\git-repos\patterns-library
npm info lifecycle @axa-ch/patterns-library@2.0.1-beta.160~posttest-child-spawn-nodejs: @axa-ch/patterns-library@2.0.1-beta.160
npm verb exit [ 0, true ]
npm timing npm Completed in 190002ms
npm info ok |
My comment was more about the path to // Node does not support PATHEXT on Windows
const npmCmd = process.platform === 'win32' ? 'C:\\eplatform\\tools\\node\\npm.cmd' : 'npm'; If there is no difference in behaviour (i.e. the slowness still occurs) this would rule out the manual path walking code on Windows in libuv (even though you specify |
@richardlau Further more running git like |
Could you attach debugger to the node child process and provide the call stack? You can get VS Community from here, from it |
I have the same issue. I'm using Windows 7 in our company environment with proxy set up.
And the results are:
But if I run plain
Then the timing is instant:
What's interesting is that every time I run it the timings are more or less around 189 sec. I see that others in this topic have also similar timings. Looks like a 3 minutes (180 sec) timeout after which the process is starting up. |
@piotrpeszt npm run test-child-spawn
> @axa-ch/aletheia@0.0.2-beta.39 test-child-spawn E:\IdeaProjects\aletheia
> node ./build/scripts/test-child-spawn.js
Message received in 1629.977086 ms
manuel-jenny
Message received in 1605.18016 ms
andyogo <andy.782542@gmail.com>
axa-ch-user <aem@axa.ch>
davidknezic <davidknezic@gmail.com>
linasalih <lina.salih@axa-winterthur.ch>
lucamele <lucamele1@hotmail.com>
manuel-jenny <git@manueljenny.ch>
sventschui <sventschui@gmail.com>
thedadi <difada1@hotmail.com> Still having issues on my working machine though since I cannot disable the realtime protection... |
I tried, but it didn't help. |
Does anyone have a fix for that? We do also use NPM behind a company proxy and child processes are extremely slow. |
@AndyOGo the workaround that is mentioned in issue npm/npm#20979 did the trick for me. You could try that out, too. Looks like npm's version check takes a lot of time if it is used in a child process. |
@NicoEnking Very interesting data, like:
This whole proxy support story dates back a few years 😱 |
Since npm moved to another issue tracker, I just recreated the issue here: Please add your thoughs, issues over there. |
@AndyOGo no problem. A Nativescript dev helped me figure this out :-) |
@NicoEnking const { execFile } = require('child_process');
const precise = require('precise');
const timer = precise();
// Node does not support PATHEXT on Windows
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
const env = {
...process.env,
// only this works for us
NO_UPDATE_NOTIFIER: true,
}
timer.start();
execFile(npmCmd, ['whoami', '--no-update-notifier' /* does not work */], { env }, (error, stdout, stderr) => {
timer.stop();
console.log('Message received in', timer.diff() / 1000000, 'ms');
if (error) {
console.error(error);
} else {
console.log(stdout);
}
const timer2 = precise();
timer2.start();
execFile('git', ['status'], (error, stdout, stderr) => {
timer2.stop();
console.log('Message received in', timer2.diff() / 1000000, 'ms');
if (error) {
console.error(error);
} else {
console.log(stdout);
}
});
}); |
I think I ran into this bug through |
This issue has been open for over a year without a conclusion and without even a clear indication it's a Node.js bug (as opposed to, say, an npm issue or an overzealous virus scanner.) I'm closing it out. Let me know if there is reason to reopen. |
v10.5.0
Utilising
child_process.execFile
at windows takes minutes to finish.To demonstrate the bug I created a timed script, running
npm whoami
first andgit status
afterwards. I compared those measured results between MacOS and Windows. Following are my results and all the details:Test run with native
child_process.execFile
npm whoami
1256.060359 ms
=1.256 sec
189733.792206 ms
=189.7338 sec
=3.162 min
151.0547
timesgit status
16.693848 ms
(x75.24091264039304
times faster)161.197277 ms
(x1177.02851894948573
times faster)9.6561
timestest script:
Windows 10:
Mac OSX El Capitan Version 10.11.6:
Related Bugs (but all closed, why?):
#3145
#3429
#7652
Btw
PATHEXT
is still not supported on windows, why is the related bugs closed then?nodejs/node-v0.x-archive#2318
The text was updated successfully, but these errors were encountered: