首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >排队API调用以适应速率限制

排队API调用以适应速率限制
EN

Stack Overflow用户
提问于 2013-09-09 05:29:09
回答 1查看 1.8K关注 0票数 2

使用全接触API,但速率限制为300次/分钟。我目前已经设置它在上传电子邮件的CSV文件时进行API调用。我想让它排队,这样一旦达到速率限制或进行300次呼叫,它就会等待1分钟并继续进行。然后我会把delayed_job放在上面。我该怎么做呢?一种快速的解决方法是使用

代码语言:javascript
复制
sleep 60 

但我如何找到它,使它已经发出300个呼叫,让它休眠或将其排队等待下一组?

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

发布于 2013-09-09 07:05:57

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

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

基本思想是,我有一个request方法,它将单个请求拆分为一个请求参数队列(基于api允许的每个请求的最大对象数),然后另一个方法迭代该队列,并调用一个将实际请求发送到远程服务器的块。如下所示:

代码语言:javascript
复制
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

要使用它:

代码语言:javascript
复制
make_multiple_requests(queue) do |request|
  your_request_method_goes_here(request)
end

这里的主要好处是,如果请求花费的时间超过了允许的时间间隔,您不必等待sleep完成,并且可以立即启动下一个请求。它只是保证下一个请求至少在间隔过去之前不会启动。我注意到,即使时间间隔设置正确,我偶尔也会收到来自API的'over-quota‘响应。在这些情况下,将在经过适当的时间间隔后重试请求。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18688831

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档