おもしろwebサービス開発日記

Ruby や Rails を中心に、web技術について書いています

ActiveJob はまだちょっと使うには早いかも

Rails 4.2 から導入された ActiveJob は、sidekiq や resque などのバックグラウンドジョブ系 gem を、同じ利用方法で扱えるようにしてくれます。

これは便利だなーと思い、sidekiq を ActiveJob を通じて使ってみたのですが、しばらく使った後に「まだ本格的に使うのは早いかも」と感じました。

リトライ機能が貧弱

sidekiq は、ジョブが失敗した時にリトライする機能があります。失敗するたびに次にリトライする間隔が伸び、一定回数失敗したら完全に失敗として扱われます。リトライ間隔や、完全に失敗になるまでの回数はもちろん変更可能です。

Web上でリトライしているジョブや完全に失敗したジョブを確認することもできます。

ActiveJob を使うと、この細やかなリトライ機能を失うことになります。例えば、次のように例外を拾って再度キューにジョブを入れることはできますが、リトライ間隔や最大のリトライ回数などはサポートしていません。この場合は無限にリトライすることになってしまいますね。

class SiteScrapperJob < ActiveJob::Base
  rescue_from(ErrorLoadingSite) do
    retry_job queue: :low_priority
  end

  def perform(*args)
    raise ErrorLoadingSite if cannot scrape
  end
end

リトライをサポートしてくれる gem

gocardless/activejob-retry という gem があります。これを使えば問題は解決しそうですが、READMEを読むと

This is an alpha library in active development, so the API may change.

との事なので、まだ実践で使うには早いのかなと思います。また、仮に alpha でなくなったとしても、ActiveJobの性質上、sidekiq の WebUI でリトライしているジョブの数を確認したりはできないはず。

まとめ

ActiveJob を使うと、様々なバックグラウンドジョブ系の gem を意識せず同じ使い方で使えるのがメリットだと思います。しかし1つの gem をずっと使うのであれば、その gem 特有の機能が使えなくなるデメリットが大きいように思えます。個人的には、今の段階ではなるべく ActiveJob は避けていくのがよいのかなと思います*1

*1:deliver_later くらいなら問題ないと思います