dimon_durak
@dimon_durak
Дурак это не фамилия, дурак - это профессия

Как правильно подключать и использовать внешние модули в ImpressAS?

Разобрался, как работают воркеры, но теперь не могу понять, как мне из воркера вызывать модули из node_modules.

Вот что у меня сейчас есть:

Файл get.js:

module.exports = function(client, callback) {
  if (client.query.mode == 'upload') {client.fork('upload')};
  callback();
};


Файл upload.js:
этот код я сначала отдельно запускал руками и он работал. При переносе на Impress я заменил только объявления переменных fs и expat (было через require, стало через IAS).

module.exports = function(client, callback) {
//  var fs = require('fs');
//  var expat = require('node-expat');
  var fs = api.fs;
  var expat = api.node-expat;
  var inputFile = application.dir + '/files/okved/xml/SpOKVED-lite.xml';
  var outputFile = inputFile.replace(/xml/g,'json');

  console.log('\n           =========== start worker %s ===========\n','"upload"');
  console.log(' > upload.worker load data from: %s ', inputFile);

  var parser = new expat.Parser('UTF-8');   // вот тут Импресс выбрасывает ошибку
  var okveds = '';

  parser.on('startElement', function (name, attrs) {
    var okved = {};
    console.log(' > parse element <%s>', name);

    if (attrs.Id) {okved.id = attrs.Id};
    if (attrs.Kod) {okved.kod = attrs.Kod};
    if (attrs.GRUP) {okved.group = attrs.GRUP};
    if (attrs.Razdel) {okved.section = attrs.Razdel};
    if (attrs.Podrazdel) {okved.subSection = attrs.Podrazdel};
    if (attrs.OKVED) {okved.OKVED = attrs.OKVED};
    if (attrs.Name) {okved.name = attrs.Name};
    if (attrs.NameP) {okved.fullName = attrs.NameP};
    if (attrs.Prim) {okved.description = attrs.Prim.split('^').join('\n')};

    if ('OKVED' in okved) {
      console.log('   + done. Found okved %s',okved.id);
      okveds += JSON.stringify(okved)+'\n'; 
    }          
    else {console.log('   - in element <%s> okved not found',name)};
  });

  fs.readFile(inputFile, function(err, data) {
    if (err) {console.dir(err)};  
    parser.write(data);

//    fs.writeFile(outputFile, okveds, function(err) {
//      if(err) {console.log(err)} else {console.log(' +++ okved saved to %s',outputFile)};
//    });
  });

  console.log('           =========== worker %s end ===========','"upload"');
  callback();
};


Если дёрнуть за урл с параметром ?mode=upload то воркер создаётся, но вываливается с ошибкой:

=========== start worker "upload" ===========

 > upload.worker load data from:  <правильный путь до>/files/okved/xml/SpOKVED-lite.xml

2015-10-02T13:57:20.884Z        Worker(5100/C1L36)      [impress]       TypeError: application.domain.client.error is not a function
  EventEmitter.application.catchException (impress.application.js:69:33)
  Domain.fnWrapper (impress.client.js:789:25)
  Domain.run (domain.js:191:14)
  impress.client.js:803:33
  impress.application.js:147:9
  FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:380:3)
Impress shutting down


У меня есть ощущение, что что-то не так при подключении модуля, который был установлен через npm.

Я делал npm install node-expat, после чего добавил 'node-expat' в файлы config\sandbox.js и applications\my-app\config\sandbox.js

Что же я делаю не так?
  • Вопрос задан
  • 263 просмотра
Решения вопроса 1
MarcusAurelius
@MarcusAurelius Куратор тега Node.js
автор Impress Application Server для Node.js
Теперь подключение модулей несколько изменилось, для этого случая в /applications/my-app/config/sandbox.js в раздел api добавьте 'node-expat' и тереь из любого обработчика можно будет обращаться к нему как api.nodeExpat. Не забудьте обновить версию Impress до сегодняшней 0.1.372, там исправлена проблема с заменой тире в именах модулей, т.е. преобразованием spinalToCamel, например: node-expat в nodeExpat, потому, что писать api['node-expat'] как-то не красиво, лучше api.nodeExpat и я это поправил.

Теперь о случае с аплоадом, в Вашем коде почему-то не видно где происходит аплоад файла, а сразу начинается парсинг. Если Вы хотите делать аплоад, то его нужно делать в обработчике post.js, а потом для парсинга уже и для других долгих операций ответветвлять процесс. Вообще, имеет ли смысл ответвлять процесс - это большой вопрос, потому как fork работает не быстро, а новый процесс ест память, так что, если парсинг быстрый (занимает десятки миллисекунд), то нет смысла его форкать, а если это несколько секунд блокирования процесса, то да - тут нужно форкать.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы