@kyanny's blog

Write down what I learnt.

Resque でジョブの実行に失敗したとき通知などをする機構の作り方 / How to write resque's failure backend

(English version is written after Japanese version)

Resque には失敗したジョブを Redis に貯めておいてエラー内容を確認したりジョブをリトライさせられる機能がある。これは Failure Backend というメカニズムで成り立っている。ジョブが失敗したらメールで通知するシンプルな Failure Backend を作りながら、このメカニズムへの理解を深めてみよう。

独自の Failure Backend を利用する手順はこうだ。

  1. Resuqe::Failure::Base を継承したクラスを作る
  2. save メソッドを定義してその中で何か面白いことをする (メールを送るとか)
  3. Resque がその Failure Backend を利用するように設定する

例としてジョブの失敗内容をメールする Failure Backend はこのように書ける。


https://gist.github.com/4125211#file_email_notification.rb

この Failure Backend を Resque から利用できるようにするには、以下のように設定する。 Rails であれば config/initializers/resque.rb あたりに書くのが適切だろう。


https://gist.github.com/4125211#file_resque_config.rb

デフォルトではResque::Failure::Redis が選ばれているのでジョブが失敗すると Redis に保存される。 Resque::Failure.backend= に Failure Backend のクラスを代入すればそのクラスが使われるが、 Redis へ保存する仕組みは残しつつメール通知も行いたいなど、複数の Failure Backend を同時に使いたい場合は Resque::Failure::Multiple を使う。

あとはジョブを失敗させれば、 Redis に保存される従来の機能を活かしたまま、メールで通知を受け取ることができる。

f:id:a666666:20121122002516p:plain

f:id:a666666:20121122002521p:plain

検証に使ったコードは Gist で公開している


Normally Resque saves failed jobs in Redis, so you can both check the backtrace and retry the job. These feature is made up of Failure Backend mechanism. Let's write a simple email notification class and study about Failure Backend deeply.

You can use your own Failure Backend in three steps.

  1. Create a class inherited the Resque::Failure::Base
  2. Define save method then write something you want to do (e.g. sending email)
  3. Tell Resque to use this class as a failure backend

For example, an email notification Failure Backend is below.


https://gist.github.com/4125211#file_email_notification.rb

For to make Resque to use this Failure Backend, make the follow settings. In Rails case, these settings will fit at config/initializers/resque.rb.


https://gist.github.com/4125211#file_resque_config.rb

The default Failure Backend is Resque::Failure::Redis so failed jobs are saved to Redis. To use your own class, assign the Failure Backend class to Resque::Failure.backend=. But probably you want to use both Redis store and email notification, so try to use Resque::Failure::Multiple and to use multiple failure backends at a same time.

When a job failed, you can receive an email notification without spoiling Redis store.

f:id:a666666:20121122002516p:plain

f:id:a666666:20121122002521p:plain

Full example code is published at Gist.