2013-12-06 6 views
0

Я пытаюсь создать очень простой веб-сервис с Goliath и Grape. Все, что мой сервис будет делать, это то, что с учетом пути изображения и целевого измерения он вернет новую геометрию изображения. Изображения хранятся на том же сервере, что и хост веб-службы.Использование Rmagick с eventmachine

Так у меня есть этот код в Grape:

# some Grape code omitted 
get "/" do 
    EM.defer { 
    image = Magick::Image.read('path to image').first 
    image.change_geometry('3000x3900') do |cols, row, img| 
     return {width: cols, height: row} 
    end 
    } 
end 

Когда я посещаю конечную точку в браузере все, что я получаю эту строку

"#<ConditionVariable:0x007ffd9de1f6e8>" 

Без EM.defer возвращает следующий JSON, но с очень низкими запросами/сек (около 4 Reqs/сек):

{width: 'new width', height: 'new heigth'} 

Как я мог сделать оперу RMagick не блокируя и заставляя его возвращать результаты?

+0

См. Http://eventmachine.rubyforge.org/EventMachine.html#defer-class_method, параметр 'op' является' & block' из вашего кода, он выполняется в отдельном потоке, параметр 'callback' на другом рука - это блок кода, который запускает реактор, как только «EM.defer» возвращает результат. Посмотрите, сможете ли вы вернуть ответ из блока обратного вызова EM.defer. – bbozo

ответ

0

Похоже, вы немного смешались.

Звонок RMagickвсегда блокировка, так как для этого требуется изображение для обработки. Хорошей новостью является звонок grape сам по себе неблокирующий. Это означает, что, пока ваши одиночные клиенты должны дождаться заявленных 1/3 секунд для завершения, клиенты еще все еще могут запросить очереди.

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

Надеюсь, это поможет.

+0

Я знаю, что Rmagick блокирует мое приложение, поэтому я попытался использовать с ним EM.defer. Возможно, что-то не так с моей реализацией EM.defer? –

+0

Я предлагаю вам «Синатра» за вашим «Виноградом», верно? Вам не нужно повторно реализовывать функциональность 'Sinatra', пожалуйста, обратитесь к опции' threaded' [здесь] (http://www.sinatrarb.com/intro.html). В любом случае, реализация 'EM # defer' внутри блока' get' неверна, так как клиент ждет ответа здесь, и вы не можете предотвратить блокировку из уже заблокированного метода. – mudasobwa

+0

Вы можете, однако, не блокировать нить реактора для всех других запросов, поэтому OP использует EM.defer – bbozo

 Смежные вопросы

  • Нет связанных вопросов^_^