Ошибка NodeJS в Linux при выполнении child_process.fork?

#node.js #fork #child-process

#node.js #fork #дочерний процесс

Вопрос:

Я не могу надежно заставить разветвленный дочерний процесс отправить родительскому сообщение, превышающее 219262 байта.

Проблема только в Linux. В Windows это работает так, как ожидалось. И эта проблема, похоже, была введена между версиями узлов 1.0.1 и 1.0.2 — отлично работает на версиях узлов до 1.0.1, но не после.

(параметр maxBuffer не имеет отношения к child_process.fork, он применяется только к child_process.exec и child_process.execFile)

Ниже приведен неудачный пример. Выполнение «родительского узла» в командной строке не приведет к выводу дочернего «messageToParent», если он превышает 219262 байта в Linux.

parent.js является:

 var cp = require('child_process');
var child = cp.fork('./child', [], {});

console.log('>>>PARENT ---> SENDING MESSAGE TO CHILD');
child.send({});

child.on('message', function(msg) {
  console.log('>>>PARENT ---> MESSAGE RECEIVED FROM CHILD = '   JSON.stringify(msg));
});
child.on('error', function(err) {
  console.log('>>>PARENT ---> ERROR FROM CHILD. err = '  err);
});
child.on('exit', function(code, signal) {
  console.log('>>>PARENT ---> EXIT FROM CHILD. code=' code ' signal = '  signal);
});
child.on('close', function(code, signal) {
  console.log('>>>PARENT ---> CLOSE FROM CHILD. code=' code ' signal = ' signal);
});
child.on('disconnect', function() {
  console.log('>>>PARENT ---> DISCONNECT FROM CHILD');
});
 

child.js является

 process.on('message', function(messageFromParent) {

  console.log('>>>>>>CHILD ---> RECEIVED MESSAGE FROM PARENT');
  var messageToParent = "It would be too long to post on stackoverflow, but if I make this string longer than 219262 bytes, it fails to return to the parent in Linux. There is no such issue in Windows";                                                                                                  
  var ret = process.send(messageToParent);
  console.log('>>>>>>CHILD ---> SENDING MESSAGE TO PARENT process.send returned '   ret);
  process.exit(0);
});

process.on('uncaughtException', function(err) {
  process.send({ output: {ERROR:err} });
  process.exit(-1);
});
 

Ответ №1:

Отправка ответа на случай, если кто-нибудь еще столкнется с этой проблемой (https://github.com/nodejs/node/issues/36268 )

Вышеупомянутый дочерний элемент.js отлично работает в версиях узлов до версии 1.0.1, поскольку функция child_process.fork() раньше была синхронной. Таким образом, «process.send (messageToParent)», за которым следует «process.exit (0)», всегда будет возвращать messageToParent в parent.js . Однако в более поздних версиях Node process.send() выполняется асинхронно. Следовательно, дочерний элемент должен выйти через process.exit() внутри процесса.отправьте обратный вызов, иначе между потоком javascript версии 8 и каналом IPC будет создано условие гонки.

Кроме того, в Windows буфер канала IPC по умолчанию достаточно велик, чтобы сообщение всегда возвращалось родительскому перед выходом дочернего элемента. В Linux это не так. Это объясняет, почему приведенный выше код работает в Windows даже с более поздними версиями Node, где process.send() является асинхронным.