Как сделать безопасными ruby вызовы API и поток записи CSV? - PullRequest
1 голос
/ 02 апреля 2020

Я пытаюсь создать программу, которая читает большой файл 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 показывает мне, что некоторые запросы были сделаны несколько раз. Я прочитал о синхронизации мьютекса и попробовал это, но это замедлило мой код плюс я использую его неправильно. Если кто-нибудь сможет помочь мне разобраться с моим недоразумением, я буду очень признателен!

...