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 に答える