使用Full Contact API,但速度限制为300calls /分钟。我目前要设置它在上传电子邮件的CSV文件时进行API调用。我想排队,一旦它达到速率限制或300次通话,它等待1分钟然后继续。然后我会把delayed_job放在上面。我怎样才能做到这一点?快速解决方法是使用
sleep 60
但是我如何找到它已经进行了300次调用,让它睡眠或将它排队等待下一组呢?
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
hashy = row.to_hash
email = hashy["email"]
begin
Contact.create!(email: email, contact_hash: FullContact.person(email: email).to_json)
rescue FullContact::NotFound
Contact.create!(email: email, contact_hash: "Not Found")
end
end
end
答案 0 :(得分:2)
这里有几个需要考虑的问题 - 是否会在任何时候使用您的API密钥进行单个进程,或者是否可能同时运行多个进程?如果你有多个delayed_job
工人,我认为后者很可能。我没有使用delayed_jobs
足以为你提供一个很好的解决方案,但我的感觉是你只能被一个工人限制。
我目前正在处理类似的API问题,每0.5秒限制1次请求,每天最多1000次。我还没有弄清楚我想跟踪每天的使用情况,但我已经使用线程处理了每秒限制。如果您可以将限制设置为“每0.2秒1个请求”,则可能使您无需每分钟跟踪一次(尽管您仍然遇到如何跟踪多个工作人员的问题)。 / p>
基本思想是我有一个请求方法,将单个请求拆分为请求参数队列(基于api每个请求允许的最大对象数),然后另一个方法迭代该队列并调用一个块,它将实际请求发送到远程服务器。像这样:
def make_multiple_requests(queue, &block)
result = []
queue.each do |request|
timer = Thread.new { sleep REQUEST_INTERVAL }
execution = Thread.new { result << yield(request) }
[timer, execution].each(&:join)
end
result
end
使用它:
make_multiple_requests(queue) do |request|
your_request_method_goes_here(request)
end
这里的主要好处是,如果请求的时间超过允许的时间间隔,则无需等待sleep
完成,您可以立即开始下一个请求。它只是保证下一个请求直到至少间隔已经过去才会开始。我注意到即使间隔设置正确,我偶尔会从API获得“超额配额”响应。在这些情况下,请求在适当的时间间隔过后重试。