アクトインディ開発者ブログ

子供とお出かけ情報「いこーよ」を運営する、アクトインディ株式会社の開発者ブログです

Delayed::Job で絶対にやっておいた方がいいたった1つの設定

こんにちは、tahara です。

アクトインディ Advent Calendar 2015 の25日目の記事です。

これです。

Delayed::Worker.max_attempts = 0

Delayed::Job は実行に失敗した場合、デフォルトで25回リトライします。 気のきいた機能なのですが、メール一斉送信を Delayed::Job でおこなう場合に悲劇をまねきます。 はい、昨日やらかしちゃいました ヘ(゚∀゚ヘ)アヒャ

例えば最初の3人にメールを送ったところで4人目でエラーとなったとします。 Delayed::Job はリトライをおこない、また最初の3人にメールを送り4人目でエラー、を繰り返します。 最初の3人に何度も同じメールが... すみませでした!

リトライしないように

Delayed::Worker.max_attempts = 0

やっておきましょう。

以下は、おまけです。

config/initializers/delayed_job_config.rb

# 失敗したジョブを消さない
Delayed::Worker.destroy_failed_jobs = false
# リトライしない
Delayed::Worker.max_attempts = 0
# ActFluentLoggerRails::Logger がバッチでも
# ちゃんとログをはくよう flush_immediately: true を指定
Delayed::Worker.logger = ActFluentLoggerRails::Logger.new(flush_immediately: true)

# エラーがあった場合に Exception Notification で通知するプラグインを作る
class Actindi::DelayedJobExceptionNotificationPlugin < Delayed::Plugin
  callbacks do |lifecycle|
    lifecycle.around(:invoke_job) do |job, *args, &block|
      begin
        block.call(job, *args)
      rescue Exception => exception
        # ActiveRecord::RecordNotFound などでも通知するために
        ignored_exceptions = ExceptionNotifier.ignored_exceptions
        ExceptionNotifier.ignored_exceptions = []
        begin
          ExceptionNotifier.notify_exception(exception,
                                             data: { job: job.inspect })
        ensure
          ExceptionNotifier.ignored_exceptions = ignored_exceptions
        end
        raise
      end
    end
  end
end
# プラグインを登録する
Delayed::Worker.plugins << Actindi::DelayedJobExceptionNotificationPlugin

これくらいとおくと安心かな。