0

紛らわしいタイトルで申し訳ありません。私の質問に合うものを思い付くのは困難でした。

私が何をしようとしているのかを説明するために、類似の例を使用します: 用語の配列が提供されると、Twitter でこれらすべての用語を検索し、ツイートを返す API 呼び出しを作成したいとします。

一方では、次のような単純なことを行うことができます (疑似コードを許していただければ):

results = []
search_terms.each_with_index do |search_term, i|
  search_uri = "http://search.twitter.com/search.json?q=#{search_term}"
  twitter_result = ... #(URI.parse, Net:HTTP:GET, start, etc.)
  results[i] = twitter_result 
end
render :json => results.to_json

しかし、もちろん、数十個のキーワードがある場合 (100 を超える場合はなおさら)、これは遅くなる可能性があります。なぜなら、Ruby は各リクエストが次のリクエストを開始するのを待たなければならないからです。

Heroku の dyno は、この作業を迅速に行うことができるように思われます (たとえば、Dyno の概要では、「dynoから直接発信リクエストを発信することが可能である」と述べています)。ただし、これらにアクセスする手段は、Delayed Jobs や Resque などを使用する傾向があるようで、これらの使用例は、私が概説したものとは大きく異なる傾向があります。

私が知る限り、複数の dyno/worker を利用するこれらの手段は、典型的なスレッドのようには機能しません: 呼び出し元/親関数によってインスタンス化されたインスタンス変数にアクセスして変更します。私が知る限り (間違っている場合は訂正してください)、通常、それらは独自のメモリ、独自の変数を使用し、他の関数がアクセスする必要があるものはすべて、キャッシュまたはデータベースを介して行われます。

よし、それでこのアイデアが不可能になるわけではない。回避策は、これらを作成した後DelayedJobs、DB から取得する親関数で (タイムアウトを使用して) 無期限ループを実行し、結果のサイズがキーワードの数と等しいかどうかを確認し、それ以外の場合は短時間スリープして再試行することです。 . はDelayedJobs、タスクの実行後にこれらの行を作成します。これは特に優れた解決策ではなく、サーバーに少し余分な作業を引き起こしますが、検索の数が増えると、単にループするよりもはるかに高速になるでしょう。

ここに質問があります(最初の質問に関連するいくつかの関連する質問があります):

私が疑問に思っているのは、呼び出されたときに新しいワーカーをすばやく起動し、いくつかのリクエストを並行して実行し、これらのリクエストがすべて完了した後に呼び出し元に応答するリクエストを Heroku で設定することがどれほど実現可能かということです。 ?

ワーカーをスピンアップして実行するのに必要な時間は、DelayedJobsこれを機能させるには多すぎますか? (リクエスト全体の長さは、できれば数秒で済みます。)

を使用するのではなく、順番に実行する方が良いリクエストのカットオフ数について何か提案はありますDelayedJobsか (私はそうは思わないでしょう。また、どの時点でどちらのオプションにルーティングするかを決定するために、これについて実験とベンチマークを行う必要があると思います。)

このプロセスを簡素化する (または、より効果的な) 他のオプションを見逃していませんか?

編集:追加のワーカーは、必要に応じて宝石 ( Hirefireなど)を使用してスピンアップされることにも注意してください。これがどの程度考慮されるかはわかりません。

4

1 に答える 1

1

Ruby では、外部 API から情報を取得することはブロッキング タスクです。つまり、このリクエストを実行しているプロセスまたはスレッドは、基本的に応答を待っている間はスリープ状態になります。

バックグラウンドで多くの同時 I/O を実行する (Twitter の検索、他の HTTP リクエストなど) ために、Ruby/Rails の世界で私が選んだライブラリはSidekiqです。Wiki で、delayed_job および resque に対する効率と利点について読むことができます。

于 2012-12-03T21:12:01.087 に答える