2016-01-06 3 views
0

Я использую HTTParty для создания запросов и в настоящее время имеют следующий код:Схватив JSON данные API с многопоточными запросами

def scr(users) 
    users.times do |id| 
    test_url = "siteurl/#{id}" 
    Thread.new do  
     response = HTTParty.get(test_url) 

     open('users.json', 'a') do |f| 
     f.puts "#{response.to_json}, " 
     end 
     p "added" 
    end 
    end 
    sleep  
end 

Это работает нормально для 100-300 записей.

Я попытался добавить Thread.exit после sleep, но если я задаю пользователям что-то вроде 200000, через некоторое время мой терминал выдает сообщение об ошибке. Я не помню, что это было, но это что-то о потоках ... ресурс занят, но некоторые записи. (Около 10000 были успешно добавлены.)

Похоже, я делаю это неправильно и вам нужно как-то разорвать запросы на партии.


до

вот что я получил:

def scr(users) 
threads = [] 
urls = [] 

users.times do |id| 
    test_url = "site_url/#{id}" 
    urls<<test_url 
end 

    urls.each_slice(8) do |batch| 
    batch.each do |t| 
     threads << Thread.new do 
     response = HTTParty.get(t) 
     response.to_json 
     end 
    end 
    end 

all_values = threads.map {|t| t.value}.join(', ') 
open('users.json', 'a') do |f| 
    f.puts all_values 
end 

ответ

1

На быстрой проверки, проблема, казалось бы, что у вас есть условие гонки с относительно файла JSON. Даже если вы не получите сообщение об ошибке, вы обязательно получите поврежденные данные.

Самым простым решением является, вероятно, просто сделать все написанное в конце:

def scr(users) 
    threads = [] 
    users.times do |id| 
    test_url = "siteurl/#{id}" 
    threads << Thread.new do  
     response = HTTParty.get(test_url) 
     response.to_json 
    end 
    end 
    all_values = threads.map {|t| t.value}.join(', ') 
    open('users.json', 'a') do |f| 
    f.puts all_values 
    end 
    end 

был не в состоянии проверить, но это необходимо сделать трюк. Также лучше использовать Thread#join или Thread#value вместо sleep.

+0

это бросает «Слишком много открытых файлов - сокет (2) для порта« site_url »443', но я думаю, что это не проблема с кодом. – kirqe

+0

@railsr: Я должен был подумать об этом. Да, вам нужно оценить лимит. Подождите - я отредактирую ответ. – Linuxios

+0

@railsr: У меня нет времени, чтобы на самом деле написать код прямо сейчас, но суть в том, что у вас есть * n * threads (скажем, 4 или 8), каждый из которых, в последовательности 1/* n * th задач. Затем вы получаете результаты, подобные приведенному выше. – Linuxios

Смежные вопросы