构建轮询外部服务(RoR)的最佳方式



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

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

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

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

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

看到这个答案:在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连接将被阻止。如果你担心,就用伤寒。有关详细信息,请参阅以下答案:在Ruby中执行非阻塞I/O的首选方式是什么?

相关内容

  • 没有找到相关文章

最新更新