1

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

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

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

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

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

4

1 回答 1

0

请参阅此答案:在 Ruby 中使用超时发出 HTTP HEAD 请求

基本上你为已知的 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。有关详细信息,请参阅此答案:在 Ruby 中执行非阻塞 I/O 的首选方法是什么?

于 2013-07-25T22:46:52.380 回答