使用typhoeus加速耙任务

时间:2016-09-27 12:12:03

标签: ruby-on-rails ruby

所以我偶然发现了这个: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它不会?

如果可以提供一个例子?

萨姆

1 个答案:

答案 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