web-dev-qa-db-fra.com

Désactiver les tentatives automatiques avec ActiveJob, utilisé avec Sidekiq

Existe-t-il un moyen de désactiver les tentatives automatiques avec ActiveJob et Sidekiq?

Je sais qu'avec Sidekiq seulement, il suffit de mettre 

sidekiq_options :retry => false

comme mentionné ici: https://github.com/mperham/sidekiq/wiki/Error-Handling#configuration

mais cela ne semble pas fonctionner avec ActiveJob et Sidekiq.

Je connais aussi la solution pour désactiver entièrement la tentative comme proposé ici: https://stackoverflow.com/a/28216822/2431728

Mais ce n'est pas le comportement dont j'ai besoin.

15
Jules Ivanic

D'accord, merci pour la réponse.

Juste pour information, j'ai également posé la question dans un problème ActiveJob Github lié à ce sujet: https://github.com/Rails/activejob/issues/47

DHP m'a répondu une solution que je n'ai pas testée mais qui peut faire l'affaire.

Personnellement, j'ai finalement mis cela dans un initialiseur afin de désactiver globalement les tentatives Sidekiq et cela fonctionne bien:

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

Il n’existe aucun moyen de configurer Sidekiq avec ActiveJob. Utilisez un Sidekiq Worker si vous ne voulez pas utiliser les valeurs par défaut.

4
Mike Perham

Vous pouvez rattraper l'exception et ne rien faire à la place ou réessayer de configurer:

  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

Pour exécuter une nouvelle tentative, vous pouvez utiliser la méthode retry_on la méthode retry_on doc

Sidekiq wiki pour les tentatives avec l'intégration active du travail

2
ilgam

J'avais le même besoin, c'est-à-dire qu'ActiveJob encapsule Sidekiq mais souhaite prendre en charge max_retries. Je mets cela dans un initialiseur. Si #max_retries est défini sur un travail ActiveJob, il sera utilisé pour définir les tentatives. Si # éphémère? est défini et renvoie true, le travail ne sera pas réexécuté et ne sera pas transféré vers "mort" s'il échoue.

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

Remarque: il est en fait important de l'ajouter à la chaîne de middleware pour le client et le serveur si l'un de vos travaux crée lui-même un nouveau travail à mesure qu'il est exécuté. 

1
verbad