我有一个Rails应用程序,其Document
标志为available
。该文档被上传到外部服务器,在那里它不能立即可用(需要时间来传播)。我想做的是轮询可用性并在可用时更新模型。
我正在为此流程寻找性能最佳的解决方案(服务不提供回调):
Document
已上传到应用我被困在3.我已经在我的项目中使用了sidekiq。这是一种选择,还是应该使用完全不同的方法(cron作业)。
Documents
将一直上传,因此首先轮询数据库/ redis以检查不可用的Documents
似乎相关。
答案 0 :(得分:0)
请参阅此答案: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?