2
2

More than 5 years have passed since last update.

buffered_job

Last updated at Posted at 2012-06-04

いくつかのジョブを一定期間バッファリングしておき、実行時に同じようなメソッドがあったら、別のメソッドをよびだす、という処理をするgemを書きました。

想定シナリオ

たとえばブログ的なサービスを運営していたとして、各記事にコメントがついたときにメール通知をしたいとします。コメント毎にメール通知していると人気のあるユーザーには毎回大量の同じようなメールがとんでしまいます。一定時間(例えば2〜3分)バッファリングしておき、同じような内容が複数存在する時には別のメソッドで受け取って本文中に展開して一通で送る、といった処理を実現するためのモジュールです

例えば下記のような処理があった場合

@article = Article.create(:user => @user,:text => "my blog article here")
c = @article.comments.create(:user => @jon, :text => "i love this article!")
@user.notify(c)

メソッドの実行をバッファしておくことにより、一定時間後に別のmerge_を頭につけたメソッドが配列になった対象オブジェクトとともに該当レシーバに送られます

c1 = @article.comments.create(:user => @jon, :text => "i love this article!")
c2 = @article.comments.create(:user => @ken, :text => "i hate this article!")

@user.buffer.notify(c1)
@user.buffer.notify(c2)
 # ここで一定期間がたつと、notifyメソッドの変わりにmerge_notifyメソッドがよばれる。
@user.merge_notify([c1,c2])  # <- これと同等の処理が実行される

インストール

Gemfile
gem 'buffered_job'

そしてbundle install。または

$ gem install buffered_job

前準備 

テーブルの作成をします

$ (bundle exec) rails generate buffered_job
$ (bundle exec) rake db:migrate

依存関係

delayed_job_active_record

ジョブの実行

delayed_job経由で行います。 delayed_job_active_recordを参考に必要なテーブルなどセットアップしたのちにワーカーを動かしてください

$ (bundle exec) rake jobs:work

使い方

全てのActiveRecordオブジェクトはbufferメソッドを持ちます。bufferをレシーバーとメソッドの間に置いてください。

@user.buffer.post_to_twitter(@article1)
@user.buffer.post_to_twitter(@aritcle2)

もしバッファリング期間後に同じレーシーバに対して、同じメソッドが複数回よばれていたら、引数を配列にまとめた上でmerge_をメソッド名の頭につけたメソッドがよびだされます。なので、この例では下記のメソッドをUserモデルに実装しておくひつようがあります

app/modesl/User.rb
def merge_post_to_twitter(articles)
   #  ..
end

現在の制限

バッファするメソッドに渡す引数オブジェクトは一つに限定してます

Configuration

デフォルトのバッファ時間は3分です。変更するには下記

BufferedJob.delay_time = 30.seconds
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2