【问题标题】:Optimal way to structure polling external service (RoR)构建轮询外部服务 (RoR) 的最佳方式
【发布时间】:2013-07-26 12:33:48
【问题描述】:

我有一个 Rails 应用程序,它的 Document 带有标志 available。文档被上传到无法立即使用的外部服务器(需要时间来传播)。我想做的是轮询可用性并在可用时更新模型。

我正在为这个过程寻找最高效的解决方案(服务不提供回调):

  1. Document 已上传至应用
  2. 应用上传到外部服务器
  3. 应用投票 url (http://external.server.com/document.pdf) 直到可用
  4. 应用更新模型 Document.available = true

我被困在 3。我已经在我的项目中使用 sidekiq。这是一个选项,还是我应该使用完全不同的方法(cron 作业)。

Documents 将一直被上传,因此首先轮询数据库/redis 以检查不可用的Documents 似乎相关。

【问题讨论】:

    标签: ruby-on-rails ruby polling


    【解决方案1】:

    看到这个答案:Making HTTP HEAD request with timeout in Ruby

    基本上,您为已知 url 设置一个 HEAD 请求,然后异步循环,直到获得 200 个返回(迭代之间有 5 秒延迟,或其他)。

    在上传文档后从控制器执行此操作:

    Document.delay.poll_for_finished(@document.id)
    

    然后在您的文档模型中:

    def self.poll_for_finished(document_id)
      document = Document.find(document_id)
      # make sure the document exists and should be polled for
      return unless document.continue_polling?
    
      if document.remote_document_exists?
        document.available = true
      else
        document.poll_attempts += 1 # assumes you care how many times you've checked, could be ignored.
        Document.delay_for(5.seconds).poll_for_finished(document.id)
      end
      document.save
    end
    
    def continue_polling?
      # this can be more or less sophisticated
      return !document.available || document.poll_attempts < 5
    end
    
    def remote_document_exists?
      Net::HTTP.start('http://external.server.com') do |http|
        http.open_timeout = 2
        http.read_timeout = 2
        return "200" == http.head(document.path).code
      end
    end
    

    这仍然是一个阻塞操作。如果您尝试联系的服务器速度缓慢或无响应,则打开 Net::HTTP 连接将阻塞。如果您担心它,请使用 Typhoeus。详情见这个答案:What is the preferred way of performing non blocking I/O in Ruby?

    【讨论】:

    • 这似乎是对 Sidekiq 工作人员的浪费。如果响应不是 200 并稍后重试该作业(例如,一分钟后),最好让作业失败。工作人员可以快速继续并尝试不同的文件。
    • @davidcelis:我根据您的反馈更新了我的答案。进一步的改进可能包括缩短超时时间或切换到 Tyohoeus 并一次批处理多个检查。
    猜你喜欢
    • 2020-05-18
    • 2012-12-22
    • 1970-01-01
    • 2010-09-30
    • 2017-04-16
    • 1970-01-01
    • 2011-03-17
    • 2010-10-18
    • 1970-01-01
    相关资源
    最近更新 更多