Я пытаюсь создать программу, которая читает большой файл CSV, затем одновременно отправляет запросы конечной точке API и, наконец, сохраняет результаты в другом файле CSV. Я читал о пулах потоков на этой странице https://blog.engineyard.com/ruby-thread-pool, а также узнал о параллельном геме ruby. Я полагал, что то, что я пытаюсь достичь, должно быть достаточно легким для достижения без использования драгоценного камня. Я использую переводчик MRI и читаю о GIL. Я думаю, так как это кажется тяжелым IO, мне не нужно было бы использовать J ruby и драгоценный камень, такой как персик. Вот что у меня есть:
array_of_stuff = CSV.read("#{file_name}")
work_q = Queue.new
array_of_stuff.flatten.each { |x| work_q .push x }
workers = (0..4).map do
Thread.new {
begin
while item = work_q.pop(true)
uri = URI.parse("https://website.com/query=" + "#{item}")
#create the HTTP protocol
http = Net::HTTP.new(uri.host, uri.port)
#set up ssl
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
#create the request
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Special #{token}"
#create the response
response = http.request(req)
if response.body == "[]\n"
print "\nNo data for #{item}\n"
next
end
#parse JSON response.
data = JSON.parse(response.body)
puts "#{item} has some data #{data[0]["Attribute"]["value"]}"
print "\Storing results to a CSV file.\n"
CSV.open("item_store.csv", "a+") do |csv|
csv << ["#{item}", "#{data[0]["Attribute"]["value"]}"]
end
end
rescue ThreadError
end
}
end
workers.map(&:join)
Я знаю, что это не работает, потому что раздел кода puts
показывает мне, что некоторые запросы были сделаны несколько раз. Я прочитал о синхронизации мьютекса и попробовал это, но это замедлило мой код плюс я использую его неправильно. Если кто-нибудь сможет помочь мне разобраться с моим недоразумением, я буду очень признателен!