Почему insert() прерывает обработчики wrapAsync'd child_process.spawn() в методе Meteor?

Я пытаюсь использовать child_process.spawn() в методе Метеор. Я хочу захватить PID, stdout, stderr и код выхода из внешнего процесса и сохранить все это в базе данных.

Все работало, пока я не добавил это первым insert() вызов. С этим insert()в базу данных вставлен только один "фиктивный" документ. Я не получаю сообщений об ошибках в консоли сервера. Если я закомментирую это первым insert(), другой insert() звонки успешны.

// server/app.js
var spawn = Npm.require('child_process').spawn;

Meteor.methods({
  start: function() {
    var child = spawn('ls', ['/tmp']);
    var pid = child.pid;

    var wrappedChildStdoutOn = Meteor.wrapAsync(child.stdout.on, child.stdout);
    var wrappedChildStderrOn = Meteor.wrapAsync(child.stderr.on, child.stderr);
    var wrappedChildOn = Meteor.wrapAsync(child.on, child);

    // this insert() breaks upcoming insert() calls!
    Stuff.insert({pid: pid, date: new Date(), type: 'dummy', data: 'dummy'});

    wrappedChildStdoutOn('data',  function (data) {
      Stuff.insert({pid: pid, date: new Date(), type: 'stdout', data: data.toString()});
    });

    wrappedChildStderrOn('data', function (data) {
      Stuff.insert({pid: pid, date: new Date(), type: 'stderr', data: data.toString()});
    });

    wrappedChildOn('exit', function (code) {
      Stuff.insert({pid: pid, date: new Date(), type: 'exit', code: code});
    });
  }
});

Что случилось с этим первым insert() вызов?

Вот приложение Meteor, демонстрирующее проблему.

1 ответ

Решение

insert занимает немного времени, так ls заканчивает вывод до insert завершается. К тому времени, когда вы поместите обработчик событий на место, будет слишком поздно.

Вы можете решить проблему, переместив первый insert до конца, двигаясь первым insert перед spawn позвонить или добавить неоперативный function () {} обратный звонок в insert так что это называется асинхронно.

Другие вопросы по тегам