Disable automatic retry with ActiveJob, used with Sidekiq

后端 未结 6 1014
名媛妹妹
名媛妹妹 2021-02-03 23:58

Is there a way to disable automatic retry with ActiveJob and Sidekiq ?

I know that with Sidekiq only, we just have to put

sidekiq_options :retry => f         


        
相关标签:
6条回答
  • 2021-02-04 00:20

    As of sidekiq 6.0.1, it is possible to pass the following to an ActiveJob worker to prevent it from retrying:

    class ExampleJob < ActiveJob::Base
      sidekiq_options retry: false
    
      def perform(*args)
        # Perform Job
      end
    end
    

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

    EDIT:

    According to this this requires Rails 6.0.1 or later as well.

    0 讨论(0)
  • 2021-02-04 00:23

    I had this same need, ie ActiveJob wrapping Sidekiq but wanting to support max_retries. I put this in an initializer. If #max_retries is defined on an ActiveJob job, it will be used to set retries. If #ephemeral? is defined and returns true, job will not be rerun and will not be transferred to 'dead' if it fails.

    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
    

    Note: it actually is important to add this to the middleware chain for both client and server if any of your jobs create new jobs themselves as they are executed.

    0 讨论(0)
  • 2021-02-04 00:31

    If you want to disable retry (or add any other Sidekiq options) for ActiveJob from gems (like for ActionMailbox::RoutingJob), you can use this approach (Rails 6.0.2+).

    1) Create a module with the desired Sidekiq options (using 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) Include it in the job class in an initializer.

    # 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 讨论(0)
  • 2021-02-04 00:40

    You can catch up the exception and to do nothing instead retry or to configure retry:

      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
    

    For running retrying you can use retry_on method retry_on method doc

    Sidekiq wiki for retries with Active Job integration

    0 讨论(0)
  • 2021-02-04 00:45

    There is no way to configure anything about Sidekiq with ActiveJob. Use a Sidekiq Worker if you don't want to use the defaults.

    0 讨论(0)
  • 2021-02-04 00:47

    Ok thanks for the answer.

    Just for information, I also asked the question in an issue related to this subject on ActiveJob Github repository : https://github.com/rails/activejob/issues/47

    DHH answered me a solution I haven't tested but that can do the job.

    Personnally, I finally put this in an initializer in order to disable Sidekiq retries globally and it works well :

    Sidekiq.configure_server do |config|
       config.server_middleware do |chain|
          chain.add Sidekiq::Middleware::Server::RetryJobs, :max_retries => 0
       end
    end
    
    0 讨论(0)
提交回复
热议问题