сервер зависает все запросы во время ожидания ответа внешнего API - PullRequest
2 голосов
/ 21 января 2012

Я использую discogs-wrapper gem для доступа к некоторой музыкальной информации, но я заметил, что во время запроса API сервер все еще не обслуживается, другие действия аналогичны функции отладчика. Я считаю, что фактический запрос запускается в следующей части гема, когда я вызываю функцию Discogs::Artist.find_by_name name.

Net::HTTP.new(uri.host).start do |http|
  http.request(request)
end

Следуя журналу двух запросов в двух разных браузерах (chrome и firefox), я сначала запускаю поиск исполнителя "pink floyd", а затем обновляю корневую страницу в другом браузере, этот последний простой запрос, который обычно занимает миллисекунды , во время запроса API занимает столько времени, сколько длится запрос.

Started GET "/artists/show?utf8=%E2%9C%93&artist_name=pink+floyd&commit=search" for 127.0.0.1 at 2012-01-21 18:03:52 +0000
Processing by ArtistsController#show as HTML
  Parameters: {"utf8"=>"✓", "artist_name"=>"pink floyd", "commit"=>"search"}
get_artist(pink floyd)
get_artist(pink floyd) - ended in 26394ms
  Rendered artists/_search_form.html.haml (4.3ms)
  Rendered discogs/artist/releases/_release.html.haml (606.5ms)
  Rendered artists/show.html.haml within layouts/application (1876.4ms)
Completed 200 OK in 28303ms (Views: 1907.8ms | ActiveRecord: 0.0ms)


Started GET "/" for 127.0.0.1 at 2012-01-21 18:04:20 +0000
Processing by ApplicationController#show as HTML
  Rendered artists/_search_form.html.haml (4.5ms)
  Rendered application/show.html.haml within layouts/application (6.5ms)
Completed 200 OK in 23ms (Views: 22.0ms | ActiveRecord: 0.0ms)

Как я могу избежать бесполезного зависания сервера для ответа, который может занять даже более 30 секунд? - спасибо

Ответы [ 2 ]

3 голосов
/ 22 января 2012

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

Распространенным решением этой проблемы является перемещение долго выполняющегося кода в отдельный фоновый процесс. Я бы не стал пытаться делать что-то вроде разветвления или запуска нескольких потоков в одном процессе rails.

Два популярных решения для фоновой обработки, которые я бы порекомендовал в это время:

Существуют и другие решения фоновых заданий, но это два самых популярных, IMO.

Чтобы дать отзыв пользователю о том, что фоновая работа завершена, на ум приходит пара вариантов.

  • Используйте AJAX для опроса сервера, чтобы увидеть, когда работа выполнена. Для resque существует ряд плагинов, которые могут помочь в этом: например, https://github.com/quirkey/resque-status или https://github.com/idris/resque-progress. Я думаю, что это просто и уместно, если работа закончится относительно быстро. Кроме того, я бы не стал делать вызов ajax слишком часто. Это будет зависеть от времени отклика вашего сервера и нагрузки, но я бы не стал делать это чаще, чем секунду или две. Если ваш сервер работает медленно или сильно загружен, этот опрос сделает его еще хуже.

  • Используйте технологию push. Я обнаружил, что Джаггернаут очень прост в использовании. Когда работа завершена, отправьте сообщение клиенту. Однако инфраструктура для ее поддержки значительно сложнее. Но это снимает нагрузку с сервера rails, и технология push может быть использована для реализации всех других интересных вещей:)

1 голос
/ 22 января 2012

Так работает rails по умолчанию: каждый экземпляр приложения обрабатывает один запрос за раз.Вы можете включить многопоточный режим (config.threadsafe!), тонкий должен нормально работать с этим

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...