将 rails 中的限制和偏移与 updated_at 和 find_each 一起使用 - 这会导致问题吗?

Using limit and offset in rails together with updated_at and find_each - will that cause a problem?

我在 Rails 项目上有一个 Ruby,其中有数百万种具有不同 url 的产品。我有一个函数 "test_response" 检查产品属性 marked_as_broken 的 url 和 returns 是真还是假,无论哪种方式,产品都已保存并具有其 "updated_at"-属性更新为当前时间戳。

由于这是一个非常乏味的过程,我创建了一个任务,该任务依次启动 15 个任务,每个任务有 N/15 个要检查的产品。第一个应该检查,例如,从第一个到第 10.000 个,第二个从第 10.000 个到第 20.000 个等等,使用限制和偏移量。

这个脚本工作正常,它从 15 个进程开始,但很快就一个接一个地完成脚本,太早了。它不会终止,它以 "Process exited with status 0" 结束。

我的猜测是,使用 find_each 和搜索 updated_at 以及实际上更新 "updated_at" 而 运行 脚本会改变一切,并且不会让脚本按预期通过 10.000 个项目,但我无法验证这一点。

我在这里做的事情有什么本质上的错误吗?例如,"find_each" 运行 一个新的 sql 查询是否偶尔会提供与预期完全不同的结果?我确实希望它提供相同的 10.000 -> 20.000,但只是将其分成几部分。

task :big_response_launcher => :environment do
  nbr_of_fps = Product.where(:marked_as_broken => false).where("updated_at < '" + 1.year.ago.to_date.to_s + "'").size.to_i
  nbr_of_processes = 15
  batch_size = ((nbr_of_fps / nbr_of_processes))-2
  heroku = PlatformAPI.connect_oauth(auth_code_provided_elsewhere)  
  (0..nbr_of_processes-1).each do |i|
    puts "Launching #{i.to_s}"
    current_offset = batch_size * i
    puts "rake big_response_tester[#{current_offset},#{batch_size}]"
    heroku.dyno.create('kopa', {
      :command => "rake big_response_tester[#{current_offset},#{batch_size}]",
      :attach => false
    }) 
  end

end

task :big_response_tester, [:current_offset, :batch_size] => :environment do |task,args|
  current_limit = args[:batch_size].to_i
  current_offset = args[:current_offset].to_i  
  puts "Launching with offset #{current_offset.to_s} and limit #{current_limit.to_s}"
  Product.where(:marked_as_broken => false).where("updated_at < '" + 1.year.ago.to_date.to_s + "'").limit(current_limit).offset(current_offset).find_each do |fp|
    fp.test_response
  end  
end

正如许多人在评论中指出的那样,使用 find_each 似乎会忽略顺序和限制。我发现这个答案 (ActiveRecord find_each combined with limit and order) 似乎对我有用。它不是 100% 有效,但确实是一个改进。其余的似乎是内存问题,即我不能在 Heroku 上同时拥有太多进程 运行。