imagemagick в meteorjs (с помощью meteor-router и файберов)

Я не могу использовать imagemagick в метеорах. Я работаю над небольшим конвертером svg->png, который содержит API-интерфейс для предоставления преобразованных изображений. Я реализовал остальные API с помощью метеора-маршрутизатора. Преобразование imagemagick работает. Но я не могу записать результат преобразования в ответ http. Я попытался исправить это, избавившись от асинхронности с помощью оптоволокна. Но это все еще не работает. По сути, все вызовы request.write игнорируются после выполнения yield. Вот мой код:

Meteor.Router.add({
  '/image/:hash' : function(hash) {

    var svg = Images.findOne({'hash' : hash}).svg;

    var request = this.request;
    var response = this.response;

    Fiber(function() {
      var fiber = Fiber.current;

      response.writeHead(200, {'Content-Type':'image/png'});

      var convert = imagemagick.convert(['svg:-', 'png:-']);

      convert.on('data', function(data) {
        response.write("doesn't work");
        //response.write(data);
      });

      convert.on('end', function() {
        response.write("doesn't work");
        //response.end();
        fiber.run({});
      });

      convert.stdin.write(svg);
      convert.stdin.end();

      response.write("works");
      Fiber.yield();
      response.write("doesn't work");
    }).run();

  }
});

Я новичок в метеорах. Поэтому я могу использовать Fiber совершенно неправильно. Или я не должен использовать клетчатку вообще. Кто-нибудь может помочь?


person David Graf    schedule 13.12.2012    source источник
comment
Я не думаю, что ваша проблема связана с волокнами, если обратный вызов convert.on('data', ...) никогда не срабатывает. Вы уверены, что этот код работает в ванильном узле? Используете ли вы node-imagemagick (github.com/rsms/node-imagemagick)? Я не смог найти ссылку на .on в их документации — они предлагают передать второй аргумент обратного вызова в .convert.   -  person avital    schedule 14.12.2012


Ответы (2)


Благодаря автору из метеора-маршрутизатора я смог решить проблему. Я неправильно использовал волокно. Как описано на странице https://github.com/laverdet/node-fibers#futures, не рекомендуется использовать волокно без абстракции между вашим кодом и необработанным API.

К счастью, волокно предоставляет одну абстракцию, называемую будущим, которую можно использовать для моего варианта использования! Вот рабочий код:

var require = __meteor_bootstrap__.require,
Future  = require('fibers/future');

Meteor.startup(function() {
  Meteor.Router.add('/image/:hash', function(hash) {
    var response = this.response;
    var fut = new Future();

    response.writeHead(200, {'Content-Type':'text/plain'});

    setTimeout(function(){ 
      response.write("hello hello");
      fut.ret();
    }, 1); 

    fut.wait();
  });
});
person David Graf    schedule 17.12.2012

Я провел еще одно расследование. Проблема ортогональна imagemagick. Например: следующие фрагменты кода также не работают в метеор-маршрутизаторе:

Пример 1:

Meteor.startup(function() {                                                        
  Meteor.Router.add({                                                              
    '/image/:hash' : function(hash) 

      var request = this.request;                                                  
      var response = this.response;                                                

      response.write("outside");                                                   

      setTimeout(function(){                                                       
        response.write("inside");                                                  
        response.end();                                                            
      }, 1); 
    }                                                                           
  }); 

Пример 2:

Meteor.startup(function() {                                                        
  Meteor.Router.add({                                                              
    '/image/:hash' : function(hash) 
      var request = this.request;                                               
      var response = this.response;                                             

      response.write("outside");                                                

      Fiber(function() {                                                        
        var fiber = Fiber.current;                                              

        setTimeout(function(){                                                  
          response.write("inside");                                             
          response.end();                                                       
        }, 1);                                                                  
        Fiber.yield();                                                          
      }).run();   
    }                                                                           
  }); 

Я думаю, что это общая проблема метеора-маршрутизатора. Потому что оба примера работают с чистыми nodejs.

person David Graf    schedule 15.12.2012