Вызов асинхронных методов с Ruby, как с Ajax - PullRequest
5 голосов
/ 11 ноября 2011

Я работаю с XMPP, и у меня есть обратный вызов сообщения, который активируется в случае каждого отправляемого сообщения.Моя цель состоит в том, чтобы отправить данные, поступающие с помощью сообщения, в API в рамках функции обратного вызова и на основе ответа отправить что-либо обратно с помощью клиента XMPP.

  1. Сообщение типа пользователя (Browser Chat Client)
  2. Сообщение поступает на сервер через XMPP
  3. Сообщение отправляется API
  4. Ответ получен
  5. Ответ отправляется обратно клиенту чата.

Мой код для этого выглядит следующим образом

admin_muc_client.activate_message_callbacks do |m|            
  sender    = m.from.resource
  room_slug = m.from.node
  message   = m.body                  

  r = HTTParty.get('http://example.com/api/v1/query?msg=message')
  Rails.logger.debug(r.inspect)
  admin_muc_client.send_message("Message #{r.body}") if m.from.resource != 'admin'
end

Меня беспокоит то, что, поскольку обратный вызов является четным, а запрос к API будет блокирующим вызовом, это может стать узким местом для всегоприложение.Я бы предпочел использовать что-то вроде AJAX для Javascript, которое будет запускать запрос и, когда ответ будет доступен, отправлять данные.Как я могу реализовать это в Ruby?

Я посмотрел на delayed_job и backgroundrb, которые выглядят как инструменты для операций fire и Забыли.Мне нужно что-то, что активирует обратный вызов в асинхронном режиме с ответом.

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

1 Ответ

5 голосов
/ 11 ноября 2011

Вы смотрели на girl_friday ? Из вики -

girl_friday - библиотека Ruby для выполнения асинхронных задач. Часто вы не хотите блокировать веб-ответ, выполняя какую-либо задачу, например, отправку электронного письма, поэтому вы можете просто использовать этот драгоценный камень для выполнения его в фоновом режиме. Он работает с любым приложением Ruby, включая приложения Rails 3.

Почему бы не использовать миллионы других асинхронных решений (Resque, DJ и т. Д.)? Поскольку girl_friday проще и эффективнее этих решений: girl_friday запускается в вашем Rails-процессе и использует шаблон субъекта для безопасного параллелизма. Поскольку он выполняется в одном и том же процессе, вам не нужно отслеживать отдельный набор процессов, развертывать отдельную кодовую базу, тратить сотни лишних МБ ОЗУ на эти процессы и т. Д. Более подробно см. Мое введение в раздел «Актеры в Ruby».

Вам нужно написать потокобезопасный код. Это не сложно сделать: шаблон актера означает, что вы получаете сообщение и обрабатываете это сообщение. Нет общих данных, которые требуют блокировок и могут привести к тупику в коде вашего приложения. Поскольку girl_friday действительно использует Threads под прикрытием, вы должны убедиться, что ваша среда Ruby может эффективно выполнять Threads. JRuby, Rubinius 1.2 и Ruby 1.9.2 должны быть достаточными для большинства приложений. Я не поддерживаю Ruby 1.8 из-за плохой поддержки многопоточности.

Я думаю, это то, что вы ищете.

...