请参阅此答案:在 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 的首选方法是什么?