所以我偶然发现了这个:https://github.com/typhoeus/typhoeus
我想知道这是否是我需要加速我的佣金任务
Event.all.each do |row|
begin
url = urlhere + row.first + row.second
doc = Nokogiri::HTML(open(url))
doc.css('.table__row--event').each do |tablerow|
table = tablerow.css('.table__cell__body--location').css('h4').text
next unless table == row.eventvenuename
tablerow.css('.table__cell__body--availability').each do |button|
buttonurl = button.css('a')[0]['href']
if buttonurl.include? '/checkout/external'
else
row.update(row: buttonurl)
end
end
end
rescue Faraday::ConnectionFailed
puts "connection failed"
next
end
end
我想知道这是否会加速它,或者因为我正在做.each
它不会?
如果可以提供一个例子?
萨姆
答案 0 :(得分:0)
如果您设置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
Ruby 可以用于纯脚本编写,但它最适合作为面向对象的语言。将您的处理工作分解为明确的方法有助于澄清您的代码并帮助您了解Tom Lord在您的问题评论中提到的内容。此外,您可以使用上面begin..rescue
中的方法级rescue
,而不是将整个脚本包装在#perform
块中,或者只包装@hydra.run
。
作为一个注释,.all.each
是一个内存耗尽,因此被认为是迭代记录的错误解决方案:.all
在使用{{1}迭代它们之前将所有记录加载到内存中}。为了节省内存,最好使用.each
或.find_each
,具体取决于您的使用案例。请参阅:http://api.rubyonrails.org/classes/ActiveRecord/Batches.html