2012-10-07 8 views
6

私はいつでも毎分(おそらく30秒ごとに)呼び出されるレーキタスクを作成しており、ポーリングAPIエンドポイント(データベースのユーザごと)に連絡します。明らかに、これは単一のスレッドとして効率的に実行されるわけではありませんが、マルチスレッドが可能ですか?そうでない場合は、ジョブを完了できる優れたイベントベースのHTTPライブラリがありますか?マルチスレッドのレーキタスク

答えて

12

私は

はRailsの起動時間の用心たびにより、毎分(将来的にはおそらく30秒ごと)と呼ばれることになるrakeタスクを書いて、フォークを使用する方がよいかもしれませんResqueやSidekiqのようなRescueは、あなたが必要とすることができるはずだが、私はSidekiqについて話すことはできないが、それは類似したものがあると確信している(SidekiqはResqueよりはるかに新しい)。

明らかに、これは単一スレッドとして効率的に実行されませんマルチスレッドが可能ですか?そうでない場合は、ジョブを完了できる優れたイベントベースのHTTPライブラリがありますか?無

# 
# Find each returns 50 by default, you can pass options 
# to optimize that for larger (or smaller) batch sizes 
# depending on your available RAM 
# 
Users.find_each do |batch_of_users| 
    # 
    # Find each returns an Enumerable collection of users 
    # in that batch, they'll be always smaller than or 
    # equal to the batch size chosen in `find_each` 
    # 
    # 
    # We collect a bunch of new threads, one for each 
    # user, eac 
    # 
    batch_threads = batch_of_users.collect do |user| 
    # 
    # We pass the user to the thread, this is good 
    # habit for shared variables, in this case 
    # it doesn't make much difference 
    # 
    Thread.new(user) do |u| 
     # 
     # Do the API call here use `u` (not `user`) 
     # to access the user instance 
     # 
     # We shouldn't need to use an evented HTTP library 
     # Ruby threads will pass control when the IO happens 
     # control will return to the thread sometime when 
     # the scheduler decides, but 99% of the time 
     # HTTP and network IO are the best thread optimized 
     # thing you can do in Ruby. 
     # 
    end 
    end 
    # 
    # Joining threads means waiting for them to finish 
    # before moving onto the next batch. 
    # 
    batch_threads.map(&:join) 
end 

これは始まります:

は、私はあなたが簡単のようなスレッドを使用して何かを行うことができ、あなたのバッチを持っていたらあなたは、あなたのファインダーのプロセスをより効率的にするためのヒントのためにActiveRecord's find_eachを見てお勧めしたいですスレッドbatch_size以上、各batch_sizeの終了を待っています。

このようなことが起こる可能性がありますが、スレッド数が制御不能になります。ここで恩恵を受ける可能性のある代替方法があります.TrapPoolや作業の共有リスト私はGithubのように投稿しましたso'asas spamoverflowflow:https://gist.github.com/6767fbad1f0a66fa90ac

+0

ThreadPoolは素晴らしいです!私はそれを試してみます –

+0

良いもの、感謝:) – Robin

3

私はsidekiqを使用することをお勧めします。これはマルチスレッドで優れています。その後、ユーザーごとに個別のジョブをエンキューして、APIをポーリングできます。 clockworkを使用して、定期的にエンキューするジョブを作成できます。

関連する問題