Отключить автоматическую повторную попытку с помощью ActiveJob, используемого с Sidekiq
Есть ли способ отключить автоматическую повторную попытку с ActiveJob и Sidekiq?
Я знаю, что только с Sidekiq, мы просто должны поставить
sidekiq_options :retry => false
как упомянуто здесь: https://github.com/mperham/sidekiq/wiki/Error-Handling#configuration
но, похоже, он не работает с ActiveJob и Sidekiq.
Я также знаю решение для полного отключения повтора, предложенное здесь: qaru.site/info/618319/...
Но это не то поведение, которое мне нужно.
Ответы
Ответ 1
Хорошо, спасибо за ответ.
Просто для информации, я также задал вопрос в проблеме, связанной с этой темой в репозитории 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
Ответ 2
Невозможно настроить что-либо о Sidekiq с помощью ActiveJob. Используйте стороннего работника, если вы не хотите использовать настройки по умолчанию.
Ответ 3
Вы можете догнать исключение и ничего не делать, вместо этого повторите попытку или настройте повтор:
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 doc
Sidekiq wiki для повторных попыток с интеграцией Active Job
Ответ 4
У меня была такая же потребность, то есть 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
Примечание: на самом деле важно добавить это в цепочку промежуточного программного обеспечения как для клиента, так и для сервера, если какое-либо из ваших заданий создает новые задания самостоятельно по мере их выполнения.