Если вы настроили Typhoeus :: Hydra для запуска параллельных запросов, вы можете быть в состоянии ускорить ваш код, если предположить, что Kernel#open
звонков, что замедляет вас. Перед оптимизацией вы можете захотеть запустить тесты для проверки этого предположения.
Если это правда, и параллельные запросы ускоряют его, вам необходимо будет перестроить свой код для загрузки событий партиями, построить очередь параллельных запросов для каждой партии и затем обработать их после их выполнения. Вот некоторый код эскиза.
class YourBatchProcessingClass
def initialize(batch_size: 200)
@batch_size = batch_size
@hydra = Typhoeus::Hydra.new(max_concurrency: @batch_size)
end
def perform
# Get an array of records
Event.find_in_batches(batch_size: @batch_size) do |batch|
# Store all the requests so we can access their responses later.
requests = batch.map do |record|
request = Typhoeus::Request.new(your_url_build_logic(record))
@hydra.queue request
request
end
@hydra.run # Run requests in parallel
# Process responses from each request
requests.each do |request|
your_response_processing(request.response.body)
end
end
rescue WhateverError => e
puts e.message
end
private
def your_url_build_logic(event)
# TODO
end
def your_response_processing(response_body)
# TODO
end
end
# Run the service by calling this in your Rake task definition
YourBatchProcessingClass.new.perform
Рубин может быть использованы для чистых сценариев, но она работает лучше всего, как объектно-ориентированный язык. Разделение вашей обработки на четкие методы может помочь прояснить ваш код и помочь вам поймать такие вещи, как Том Лорд, упомянутый в комментариях к вашему вопросу. Кроме того, вместо того, чтобы обернуть весь ваш скрипт в блоке begin..rescue
, вы можете использовать уровень метода rescue
s, как в #perform
выше, или просто обернуть @hydra.run
.
Как примечание, .all.each
является борами памяти, и, таким образом, считается плохим решением итерации записи: .all
загружает все записи в память, прежде чем итерация над ними .each
. Чтобы сохранить память, лучше использовать .find_each
или .find_in_batches
, в зависимости от вашего варианта использования. Смотрите: http://api.rubyonrails.org/classes/ActiveRecord/Batches.html
это может ускорить задачу, но ваш вопрос очень странный =) у вас уже есть код, поэтому попробуйте использовать 'Typhoeus' и посмотреть, как он будет выглядеть. – Aleksey
Производительность - сложный вопрос ... Мне действительно невозможно сказать, насколько быстрее он будет работать с HTTP-запросами, создаваемыми параллельно. Попробуй и посмотри! –
Возможно, есть некоторые другие улучшения производительности, которые вы могли бы сделать без драгоценного камня. Выполнение 'next if table == row.eventvenuename' кажется странным. Почему бы просто не пропустить эти итерации более интеллектуальным селектором, чем 'doc.css ('. Table__row - event')'? LIkewise, для 'buttonurl.include? '/ checkout/external'' - просто настройте свой селектор. –