2017-12-11 8 views
0

私は20,000から30,000人のユーザーがおり、与えられた時間にメッセージを受け取るはずです。 SendMessageは、サードパーティのサイトに対してAPI呼び出しを行うサービスです。私はこのループを持っている:大きなループのたびに新しいスレッドを呼び出す

@users.each do |user| 
    ... 
    SendMessage.new(user.id) 
    ... 
end 

ユーザーのかなりの数が多いので、APIの応答は約1秒かかり、最後のユーザーがあまりにも後でスケジュールされた時間よりメッセージを受け取ります。

私はこのようなThreadを使用するのではと思った:

@users.each do |user| 
    ... 
    Thread.new{ SendMessage.new(user.id) } 
    ... 
end 

は、私は上記のように行うことができますか?ループ内でThread.new20,000回を使用することをお勧めしますか?何か欠点はありますか?私は何か他にやるべきことはありますか?

+0

同期する必要がありますか? –

+0

いいえ、それは非同期にすることができます –

答えて

0

サードパーティプロバイダに20,000回のAPIコールを送信する必要があることを見て、これを非同期にすることができると仮定すると、SidekiqまたはResqueで実装する必要があります。

最初にリクエストを発行してから、必要に応じてステータスを更新するために連続してポーリングすることができます。

+0

私は 'Sidekiq'を使っていますが、すでにレポートを生成するためにバックグラウンドジョブを実行しています。これはあまりにも多くのジョブとサイドキックの停止をエンキューすることができます。 :/。だから私はそれを避けたかった。 –

+0

あまりにも多くの非同期操作を行い、 'Sidekiq'が助けにならない場合は、' Sidekiq'でスケールアウトするか、あなたのアーキテクチャに 'RabbitMQ'を追加してください。 –

0

まだコメントできません。しかし、私の答えが役に立たないなら、私はそれを破壊するでしょう。 eachを使用すると、すべてのレコードがメモリに読み込まれます。レコードが20,000を超えると、それは良いことではありません。 find_eachを試してみてください。 findは、バッチサイズが1000のfind_in_batches(または:batch_sizeオプションで指定されたもの)によって実行されます。

+0

ありがとう、私はこれを考慮する。 –

関連する問題