この回答を参照してください: 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 を実行する好ましい方法は何ですか?