Почему мой дочерний процесс Node, созданный с помощью spawn(), зависает?

Я использую spawn() для вызова git. Иногда он работает нормально, но иногда он зависает. Я не вижу срабатывания событий (ошибка, выход, закрытие), но вижу доказательства того, что процесс действительно завершился успешно.

var spawn = require('child_process').spawn;

spawn('git', ['push', 'origin', 'master'])
  .on('error', function(error) {
    console.log("ERROR: DETAILS: " + error);
  })
  .on('close', function(code) {
    console.log("SUCCESS: CODE: " + code);
  })
  .on('exit', function(code) {
    console.log("EXIT: CODE: " + code);
  })

person Tom    schedule 26.12.2013    source источник


Ответы (1)


Как оказалось, когда буфер stderr превышает 24 КБ, вы должны читать из него, иначе вы не увидите никаких событий для завершения. Возможные обходные пути:

  1. Установите опцию stdio в вызове spawn.

    spawn('git', ['push', 'origin', 'master'], {stdio: 'ignore'});
    

    См. документ Node ChildProcess, чтобы узнать обо всех возможностях — их много.

  2. Добавьте обработчик on(data).

    var git = spawn('git', ['push', 'origin', 'master']);
    ...
    git.stderr.on('data', function(data) {
      // do something with it
    });
    
  3. Передайте его на stdout/stderr. Это может быть слишком многословно для вашего приложения, но включите его для полноты картины.

    var git = spawn('git', ['push', 'origin', 'master']);
    ...
    git.stderr.pipe(process.stderr);
    git.stdout.pipe(process.stdout);
    
person Tom    schedule 26.12.2013
comment
Воспроизводимый случай был включен в эту проблему Node. Я считаю, что тот факт, что выход не срабатывает, является ошибкой, как и различное поведение в зависимости от размера буферов. - person Tom; 27.12.2013
comment
Как оказалось, именно так и происходит при работе с дочерними процессами. Вы должны что-то сделать с каналами stdio или рисковать зависанием дочернего процесса, потому что его каналы заполнены. Также см. этот поток . - person Tom; 31.12.2013
comment
В этом случае ребенок не висит, он уже вышел. Однако код узла не получает никаких событий. Я вижу то же самое, когда дочерний процесс ушел, но узел никогда не запускает событие выхода или закрытия, и мой код узла заблокирован, ожидая чего-то, чего не происходит. Для меня ошибка прерывистая и не на 100% надежно воспроизводима. - person legalize; 16.09.2016