Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

child_process.execFile slow to exit

I have a Node script that calls an external program (PluginManager.exe) this way:

const util = require('util');
const execFile = util.promisify(require('child_process').execFile);

const process = execFile('PluginManager.exe', ['/install']);
process
  .then(({stdout, stderr}) => console.log('done', stdout, stderr))
  .catch(e => console.log(e));

PluginManager.exe takes 8 seconds to execute. My problem is that the Node script keeps running for another 10 more seconds after the child process has exited. I know when PluginManager.exe finishes because I can see it disappear from the Windows Task Manager Process List.

What keeps the Node process running for so long and what can I do to make sure it exits as soon as the child process exits?

like image 313
Sylvain Avatar asked Apr 04 '18 16:04

Sylvain


People also ask

What is child process spawn?

child_process. spawn() method: This method launches a new process with a given command. child_process. fork() method: This method is a special case of spawn() method to create child processes.

What is exec () in node JS?

The exec() function in Node. js creates a new shell process and executes a command in that shell. The output of the command is kept in a buffer in memory, which you can accept via a callback function passed into exec() .

How does child process work in node JS?

Usually, Node. js allows single-threaded, non-blocking performance but running a single thread in a CPU cannot handle increasing workload hence the child_process module can be used to spawn child processes. The child processes communicate with each other using a built-in messaging system.


1 Answers

Maybe it's waiting on input and timing out after 10s?

Try closing stdin with .end() as mentioned in https://nodejs.org/api/child_process.html#child_process_subprocess_stdin

(in this usage, you'll need the original return value of execFile, so don't promisify, as per https://stackoverflow.com/a/30883005/1105015)

e.g.

const util = require('util');
const execFile = require('child_process').execFile;

const process = execFile(
  'PluginManager.exe', ['/install'], (e, stdout, stderr) => {
    if (e) {
      console.log(e);
    } else {
      console.log('done', stdout, stderr));
    }});
process.stdin.end();
like image 79
Rob Starling Avatar answered Oct 24 '22 20:10

Rob Starling