Асинхронный HTTP-запрос в рубине
require 'net/http'
urls = [
{'link' => 'http://www.google.com/'},
{'link' => 'http://www.facebook.com/'},
{'link' => 'http://www.yahoo.com/'}
]
urls.each do |u|
u['content'] = Net::HTTP.get( URI.parse(u['link']) )
end
print urls
Это будет работать как процедурный код. Я просто хочу поразить сервер, никаких проблем с заказом. Как я могу это сделать в рубине. Один из вариантов - использование потоков.
Вот пример использования потоков.
require 'net/http'
urls = [
{'link' => 'http://www.google.com/'},
{'link' => 'http://www.facebook.com/'},
{'link' => 'http://www.yahoo.com/'}
]
urls.each do |u|
Thread.new do
u['content'] = Net::HTTP.get( URI.parse(u['link']) )
puts "Successfully requested #{u['link']}"
if urls.all? {|u| u.has_key?("content") }
puts "Fetched all urls!"
exit
end
end
end
Любое лучшее решение..??
PS: - Я хочу попасть в mixpanel, поэтому я просто хочу сделать HTTP-вызов и не жду ответа.
Ответы
Ответ 1
Облегченная асинхронная обработка - это работа потоков (как вы сказали) или волокон.
В противном случае вы должны рассмотреть EventMachine, который является очень мощным инструментом.
РЕДАКТИРОВАТЬ: вышеуказанный URL для Event Machine мертв. Вот их учетная запись GitHub, https://github.com/eventmachine/eventmachine. Это служит хорошей отправной точкой.
Ответ 2
Вот отличная статья, посвященная теме.
В общем, жизнеспособными альтернативами использования потоков для этого было бы использование Fiber или вы могли бы использовать em-http-request. В последнем примере вы можете отказаться от обработки обратного вызова для вашей конкретной цели.
Ответ 3
Если его почти простые HTTP-запросы в асинхронном стиле, возможно, Unirest наилучшим образом подходят для его достижения.
Запрос Asnc так же прост, как:
response = Unirest.post "http://httpbin.org/post",
headers:{ "Accept" => "application/json" },
parameters:{ :age => 23, :foo => "bar" } {|response|
response.code # Status code
response.headers # Response headers
response.body # Parsed body
response.raw_body # Unparsed body
}