NodeJS не порождает дочерний процесс, кроме как в тестах

У меня есть следующий код NodeJS:

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

var Unzipper = {
  unzip: function(src, dest, callback) {
    var self = this;

    if (!fs.existsSync(dest)) {
      fs.mkdir(dest);
    }

    var unzip = spawn('unzip', [ src, '-d', dest ]);

    unzip.stdout.on('data', function (data) {
      self.stdout(data);
    });

    unzip.stderr.on('data', function (data) {
      self.stderr(data);

      callback({message: "There was an error executing an unzip process"});
    });

    unzip.on('close', function() {
      callback();
    });
  }
};

У меня есть тест NodeUnit, который успешно выполняется. Используя phpStorm для отладки теста, переменная unzip назначается правильно

Снимок экрана отладки теста phpStorm

Однако, если я запускаю тот же код как часть веб-службы, вызов spawn не возвращается должным образом, и сервер падает при попытке присоединить обработчик on к несуществующему Свойство stdout переменной unzip.

введите здесь описание изображения

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

Я использую v0.10.3 на OSX Snow Leopard (через MacPorts).

Почему я не могу правильно создать дочерний процесс?

ОБНОВЛЕНИЯ

Для @jonathan-wiepert

Я использую Прототипное наследование, поэтому, когда я создаю "экземпляр" Unzipper, я устанавливаю stdout и stderr, т.е. :

var unzipper = Unzipper.spawn({
  stdout: function(data) { util.puts(data); },
  stderr: function(data) { util.puts(data); }
});

Это похоже на концепцию "внедрения конструктора". Что касается других ваших моментов, спасибо за советы.

Ошибка, которую я получаю:

project/src/Unzipper.js:15
    unzip.stdout.on('data', function (data) {
                 ^
TypeError: Cannot call method 'on' of undefined

Согласно моим снимкам экрана отладки, объект, возвращаемый вызовом spawn, отличается в разных обстоятельствах. Мой тест проходит успешно (он проверяет, что ZIP-файл можно правильно разархивировать), поэтому проблема возникает при запуске этого кода в качестве веб-службы.


person kierans    schedule 23.04.2013    source источник
comment
Должен был быть комментарий: переносим сюда: unzip (функция) не имеет stdout или stderr, поэтому self.stdout(data); и self.stderr(данные); оба завершатся с ошибкой, например: self.stderr(data); ^ TypeError: Object # не имеет метода 'stderr' Вероятно, вам следует изменить их на console.log/error или что-то в этом роде. Кроме того, обработчик unzip.on('close'... будет вызываться, даже если в unzip.stderr отправлены данные, поэтому нет необходимости вызывать обратный вызов из обработчика stderr. Если это не проблема, отправьте сообщение сообщение об ошибке, которое вы получаете из веб-службы.   -  person Jonathan Wiepert    schedule 24.04.2013
comment
Используете ли вы какую-то структуру, чтобы запустить ее как веб-службу?   -  person Jonathan Wiepert    schedule 24.04.2013
comment
Нет, просто используя http.createServer(), обработчик, который передается, вызывает метод распаковки. Мой API очень прост, поэтому я использую свои собственные функции для обработки HTTP-запросов.   -  person kierans    schedule 24.04.2013


Ответы (1)


Проблема заключалась в том, что метод порождения, созданный на прототипе объекта (см. эту статью о прототипном наследовании), вызывал Функция child_process.spawn подлежала замене, поэтому вызывалась неправильная функция.

Я сохранил child_process.spawn в свойстве «класса» Unzipper до того, как он будет уничтожен, и вместо этого использовал это свойство.

person kierans    schedule 24.04.2013