2

Using Full Contact API, but they have a rate limit of 300calls/minute. I currently have it to set that it does an API call when uploading the CSV file of emails. I want to queue it such that once it hits the rate limit or does 300 calls, it waits for 1 minute and proceeds. Then I will put delayed_job on it. How can I do that? A quick fix is to use

sleep 60 

but how do I find it such that it made 300 calls already, make it sleep or queue it for next set?

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
4

1 回答 1

2

这里有几个问题需要考虑 - 是否会有一个进程在任何时候使用您的 API 密钥,或者是否有可能同时运行多个进程?如果你有多个delayed_job工人,我认为后者很可能。我还没有delayed_jobs足够的时间给你一个很好的解决方案,但我的感觉是你会被限制在一个工人身上。

我目前正在处理一个 API 的类似问题,限制为每 0.5 秒 1 个请求,每天最多 1000 个。我还没有弄清楚我想如何跟踪每天的使用情况,但我已经使用线程处理了每秒限制。如果您可以将限制设置为“每 0.2 秒 1 个请求”,那么您可能不必按分钟跟踪它(尽管您仍然存在如何跟踪多个工作人员的问题)。

基本思想是我有一个请求方法,它将单个请求拆分为请求参数队列(基于 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 收到“超出配额”的响应。在这些情况下,请求会在经过适当的时间间隔后重试。

于 2013-09-08T23:05:56.993 回答