Одновременные веб-запросы с Ruby - PullRequest
1 голос
/ 26 апреля 2010

У меня есть приложение Sinatra, которое в основном принимает некоторые входные значения, а затем находит данные, соответствующие этим значениям, из внешних служб, таких как Flickr, Twitter и т. Д.

Например:

вход: "Чаттануга Чу Чу" Выйти и найти изображения на Flickr на Chattanooga Choo Choo и твиты из Twitter и т. Д.

Прямо сейчас у меня есть что-то вроде:

@images = Flickr::...find...images..

@tweets = Twitter::...find...tweets...

@results << @images

@results << @tweets

Итак, мой вопрос: есть ли эффективный способ в Ruby одновременно выполнять эти запросы? Вместо того чтобы ждать окончания изображений до окончания твитов.

Ответы [ 5 ]

2 голосов
/ 26 апреля 2010

Темы будут работать, но это грубый инструмент. Вы можете попробовать что-то вроде этого:

flickr_thread = Thread.start do
  @flickr_result = ... # make the Flickr request
end

twitter_thread = Thread.start do
  @twitter_result = ... # make the Twitter request
end

# this makes the main thread wait for the other two threads
# before continuing with its execution
flickr_thread.join
twitter_thread.join

# now both @flickr_result and @twitter_result have
# their values (unless an error occurred)

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

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

Возможно, вам поможет такой инструмент, как EventMachine (в частности, подпроект em-http-request ), если вы делаете много таких вещей. Вероятно, это могло бы облегчить кодирование на более высоком уровне. Нити трудно понять правильно.

2 голосов
/ 26 апреля 2010

Возможно, вы захотите внести изменения на стороне клиента, чтобы использовать асинхронные запросы Ajax для получения каждого типа (изображения, твиттера) независимо. Проблема с серверными потоками (один из них в любом случае) состоит в том, что если один сервис зависает, весь запрос зависает, ожидая завершения этого потока. С помощью Ajax вы можете загрузить раздел изображений, раздел Twitter и т. Д., И если один из них зависнет, другие все равно покажут свои результаты; в конечном итоге вы можете тайм-аут запросов и показать сбой кита или что-то только в этом разделе.

1 голос
/ 24 сентября 2010

http://github.com/pauldix/typhoeus

параллельные / параллельные http-запросы

1 голос
/ 29 апреля 2010

Рассмотрите возможность использования YQL для этого. Он поддерживает подзапросы, так что вы можете извлечь все, что вам нужно, с помощью одного (даже на стороне клиента) вызова, который просто выплевывает JSON из того, что вам нужно визуализировать. Уже есть тонны учебников.

1 голос
/ 26 апреля 2010

Да, почему не темы?

Как я понял. Как только пользователь отправит форму, вы хотите параллельно обрабатывать все запросы, верно? У вас может быть один многопоточный контроллер (поддержка потоков Ruby работает очень хорошо.), Когда вы получаете один запрос, затем выполняете параллельно службы внешних запросов, а затем вы отвечаете в одном ответе, или на стороне клиента вы отправляете по одному сообщению ajax для каждого. обслуживать и обрабатывать его (возможно, каждый внешний сервис имеет свой собственный контроллер / действия?)

...