My Survey模型有大约2500个实例,我需要将set_state
方法应用于每个实例两次。我需要在每个实例都将方法应用于它之后第二次应用它。 (实例的状态可以取决于其他实例的状态。)
我正在使用delayed_job
创建延迟作业,workless
根据需要自动按比例放大/缩小我的工作人员dynos。
set_state
方法通常需要大约一秒钟才能执行。所以我在heroku控制台上运行了以下命令:
2.times do
Survey.all.each do |survey|
survey.delay.set_state
sleep(4)
end
end
重载API不应该是任何问题,对吗?
然而,我仍然在每个延迟工作的日志中看到以下内容:
Heroku::API::Errors::ErrorWithResponse: Expected(200) <=> Actual(429 Unknown)
我没有看到任何无限循环 - 只要我创建延迟作业,它就会立即返回此消息。
如何避免吹Heroku的API速率限制?
答案 0 :(得分:2)
回顾workless
,看起来它会为每个延迟的作业发出一个API调用,以检查工作人员数量,并可能进行第二次API调用以扩大/缩小。因此,如果您在短时间内运行5000(2500x2)个作业,您最终将获得5000+ API调用。这将超过1200 /每小时限制请求。我在那里评论过希望有助于降低整体API使用率(https://github.com/lostboy/workless/issues/33#issuecomment-20982433),但我认为我们可以为您提供更具体的解决方案。
同时,特别是如果您的工作量非常可预测(如此)。我建议你自己跳过无用的工作。即听起来你已经知道需要进行缩放(在上面的循环之前放大,然后缩小)。如果是这种情况,你可以做这样的事情来模拟无效的行为:
require 'heroku-api'
heroku = Heroku::API.new(:api_key => ENV['HEROKU_API_KEY'])
client.post_ps_scale(ENV['APP_NAME'], 'worker', Survey.count)
2.times do
Survey.all.each do |survey|
survey.delay.set_state
sleep(4)
end
end
min_workers = ENV['WORKLESS_MIN_WORKERS'].present? ? ENV['WORKLESS_MIN_WORKERS'].to_i : 0
client.post_ps_scale(ENV['APP_NAME'], 'worker', min_workers)
请注意,您还需要从这些作业中删除无效工作。我没有看到某种特定的方法来为某些工作做这件事,所以如果你需要的话,你可能想问一下这个项目。此外,如果这需要2次通过(第一次通过需要在第二次之前完成),4秒睡眠可能在某些情况下是不够的,但这是一种不同的蠕虫。
我希望这有助于缩小您的需求,但我很乐意根据需要进一步讨论和/或详细说明。谢谢!