我正在尝试在Ruby中发出多个HTTP请求。我知道它可以很容易地在NodeJS中完成。我正在尝试使用线程在Ruby中完成它,但我不知道这是否是最好的方法。我没有成功运行大量请求(例如超过50个)。
require 'json'
require 'net/http'
urls = [
{"link" => "url1"},
{"link" => "url2"},
{"link" => "url3"}
]
urls.each_value do |thing|
Thread.new do
result = Net::HTTP.get(URI.parse(thing))
json_stuff = JSON::parse(result)
info = json["person"]["bio"]["info"]
thing["name"] = info
end
end
# Wait until threads are done.
while !urls.all? { |url| url.has_key? "name" }; end
puts urls
有什么想法吗?
答案 0 :(得分:1)
你的方式可能会起作用,但它会在一个繁忙的循环中结束,当它真的不需要时会占用CPU周期。更好的方法是仅在请求完成时检查您是否已完成。实现此目的的一种方法是使用Mutex
和ConditionVariable
。
使用互斥和条件变量,我们可以让主线程等待,当其中一个工作线程收到响应时,它可以唤醒主线程。然后主线程可以查看是否还有任何URL要下载;如果是的话,它会再次入睡,等待;否则,就完成了。
等待信号:
mutex.synchronize { cv.wait mutex }
唤醒等待线程:
mutex.synchronize { cv.signal }
您可能需要检查完成情况并在thing['name']
块中设置mutex.synchronize
以避免同时访问多个线程中的数据。
答案 1 :(得分:1)
您可以调用Thread#join来使主线程等待其他线程,而不是您使用的while子句。
threads = []
urls.each_value do |thing|
threads << Thread.new do
result = Net::HTTP.get(URI.parse(thing))
json_stuff = JSON::parse(result)
info = json["person"]["bio"]["info"]
thing["name"] = info
end
end
# Wait until threads are done.
threads.each { |aThread| aThread.join }