web-dev-qa-db-ja.com

Sidekiqで使用されるActiveJobで自動再試行を無効にする

ActiveJobとSidekiqで自動再試行を無効にする方法はありますか?

Sidekiqだけで、

sidekiq_options :retry => false

ここで述べたように: https://github.com/mperham/sidekiq/wiki/Error-Handling#configuration

しかし、ActiveJobやSidekiqでは動作しないようです。

ここで提案されているように再試行を段階的に無効にする解決策も知っています: https://stackoverflow.com/a/28216822/2431728

しかし、それは私が必要とする行動ではありません。

20
Jules Ivanic

回答ありがとうございます。

参考までに、私はActiveJob Githubリポジトリのこの主題に関連する問題でも質問しました: https://github.com/Rails/activejob/issues/47

DHHは私がテストしていないソリューションを私に答えましたが、それは仕事をすることができます。

個人的には、Sidekiqの再試行をグローバルに無効にするために、最終的にこれをイニシャライザに入れ、うまく機能します。

Sidekiq.configure_server do |config|
   config.server_middleware do |chain|
      chain.add Sidekiq::Middleware::Server::RetryJobs, :max_retries => 0
   end
end
17
Jules Ivanic

ActiveJobでSidekiqを構成する方法はありません。デフォルトを使用したくない場合は、Sidekiq Workerを使用します。

5
Mike Perham

例外をキャッチして何もせずに再試行するか、再試行を構成できます。

  class ExampleJob < ActiveJob::Base
    rescue_from(StandardError) do |exception|
      Rails.logger.error "[#{self.class.name}] Hey, something was wrong with you job #{exception.to_s}"       
    end

    def perform
      raise StandardError, "error_message"
    end
  end

  class ExampleJob < ActiveJob::Base
    rescue_from(StandardError) do |exception|
      retry_job wait: 5.minutes, queue: :low_priority     
    end

    def perform
      raise StandardError, "error_message"
    end
  end

再試行を実行するには、retry_onメソッド retry_on method doc を使用できます

アクティブジョブの統合による再試行用のSidekiq wiki

3
ilgam

私もこれと同じニーズがありました。つまり、ActiveJobがSidekiqをラップしていますが、max_retriesをサポートしたいのです。これをイニシャライザに入れました。 #max_retriesがActiveJobジョブで定義されている場合、それは再試行の設定に使用されます。 #ephemeralの場合?が定義され、trueを返します。ジョブが再実行されず、失敗した場合、ジョブは「デッド」に転送されません。

class Foobar::SidekiqClientMiddleware
  def call(worker_class, msg, queue, redis_pool)
    aj_job = ActiveJob::Base.deserialize(msg['args'][0]) rescue nil
    msg['retry'] = aj_job.respond_to?(:max_retries) ? aj_job.max_retries : 5
    msg['retry'] = false if aj_job.respond_to?(:ephemeral?) && aj_job.ephemeral?
    yield
  end
end

Sidekiq.configure_client do |config|
  config.redis = { url: "redis://#{redis_Host}:6379/12" }
  config.client_middleware do |chain|
    chain.add Foobar::SidekiqClientMiddleware
  end
end

Sidekiq.configure_server do |config|
  config.redis = { url: "redis://#{redis_Host}:6379/12" }
  config.client_middleware do |chain|
    chain.add Foobar::SidekiqClientMiddleware
  end
end

注:実際にジョブの実行時に新しいジョブを作成する場合は、クライアントとサーバーの両方のミドルウェアチェーンにこれを追加することが実際に重要です。

1
verbad

sidekiq 6.0.1以降、次のコードをActiveJobワーカーに渡して、再試行を防ぐことができます。

class ExampleJob < ActiveJob::Base
  sidekiq_options retry: false

  def perform(*args)
    # Perform Job
  end
end

詳細: https://github.com/mperham/sidekiq/wiki/Active-Job#customizing-error-handling

編集:

this によると、これにはRails 6.0.1以降も必要です。

0
hananamar

GemからのActiveJobの再試行を無効にする(または他のSidekiqオプションを追加する)場合(ActionMailbox::RoutingJobなど)、このアプローチを使用できます(Rails 6.0.2+)。

1)必要なSidekiqオプションを使用してモジュールを作成します(ActiveSupport::Concernを使用)

# lib/fixes/action_mailbox_routing_job_sidekiq_fix.rb

module ActionMailboxRoutingJobSidekiqFix
  extend ActiveSupport::Concern

  included do
    sidekiq_options retry: false
  end
end

2)イニシャライザのジョブクラスに含めます。

# config/initializers/extensions.rb

require Rails.root.join('lib', 'fixes', 'action_mailbox_routing_job_sidekiq_fix')

Rails.configuration.to_prepare do
  ActionMailbox::RoutingJob.include ::ActionMailboxRoutingJobSidekiqFix
end

0
CiTroNaK