Spec-Zone.ru › Ruby on Rails 8.1

module ActiveJob::Exceptions::ClassMethods

Публичные методы экземпляра

after_discard (&blk) Показать исходный код
# File activejob/lib/active_job/exceptions.rb, line 131
def after_discard(&blk)
  self.after_discard_procs += [blk]
end

Блок, который выполняется, когда задача собирается быть отброшена по любой причине.

Пример

class WorkJob < ActiveJob::Base
  after_discard do |job, exception|
    ExceptionNotifier.report(exception)
  end

  ...

end
discard_on (*exceptions, report: false) { |self, error| ... } Показать исходный код
# File activejob/lib/active_job/exceptions.rb, line 109
def discard_on(*exceptions, report: false)
  rescue_from(*exceptions) do |error|
    instrument :discard, error: error do
      ActiveSupport.error_reporter.report(error, source: "application.active_job") if report
      yield self, error if block_given?
      run_after_discard_procs(error)
    end
  end
end

Отбросить задачу без попыток повторного выполнения, если возникает исключение. Это полезно, когда объект, связанный с задачей, например Active Record, больше недоступен, и задача, таким образом, теряет актуальность.

Передача параметра :report приводит к тому, что ошибка перед отбрасыванием задачи передаётся системе отчётов об ошибках.

Можно также передать блок, который будет вызван. Блоку передаются экземпляр задачи в качестве первого параметра и экземпляр ошибки в качестве второго.

Обработчики retry_on и discard_on ищутся снизу вверх, а затем вверх по иерархии классов. Если таковой имеется, вызывается обработчик первого класса, для которого выполняется условие exception.is_a?(klass).

Пример

class SearchIndexingJob < ActiveJob::Base
  discard_on ActiveJob::DeserializationError
  discard_on CustomAppException, report: true
  discard_on(AnotherCustomAppException) do |job, error|
    CustomErrorHandlingCode.handle(job, error)
  end

  def perform(record)
    # Will raise ActiveJob::DeserializationError if the record can't be deserialized
    # Might raise CustomAppException for something domain specific
  end
end
retry_on (*exceptions, wait: 3.seconds, attempts: 5, queue: nil, priority: nil, jitter: JITTER_DEFAULT, report: false) { |self, error| ... } Показать исходный код
# File activejob/lib/active_job/exceptions.rb, line 64
def retry_on(*exceptions, wait: 3.seconds, attempts: 5, queue: nil, priority: nil, jitter: JITTER_DEFAULT, report: false)
  rescue_from(*exceptions) do |error|
    executions = executions_for(exceptions)
    if attempts == :unlimited || executions < attempts
      ActiveSupport.error_reporter.report(error, source: "application.active_job") if report
      retry_job wait: determine_delay(seconds_or_duration_or_algorithm: wait, executions: executions, jitter: jitter), queue: queue, priority: priority, error: error
    else
      if block_given?
        instrument :retry_stopped, error: error do
          yield self, error
        end
        run_after_discard_procs(error)
      else
        instrument :retry_stopped, error: error
        run_after_discard_procs(error)
        raise error
      end
    end
  end
end

Перехватить исключение и запланировать повторное выполнение задачи через указанное количество секунд, ограничив число попыток. Если исключение продолжает возникать после указанного числа попыток, оно передаётся базовой системе очередей, которая может использовать собственный механизм повторных попыток или поместить задачу в очередь ожидания для проверки.

Можно также передать блок, который будет вызван, если попытки повторного выполнения не увенчаются успехом. Это позволяет реализовать собственную логику вместо передачи исключения дальше. Блоку передаются экземпляр задачи в качестве первого параметра и экземпляр ошибки в качестве второго.

Обработчики retry_on и discard_on ищутся снизу вверх, а затем вверх по иерархии классов. Если таковой имеется, вызывается обработчик первого класса, для которого выполняется условие exception.is_a?(klass).

Параметры

  • :wait — повторно ставит задачу в очередь с задержкой, заданной в секундах (по умолчанию: 3 секунды), вычисляемым proc, принимающим в качестве аргумента количество уже выполненных запусков, или ссылкой на символ :polynomially_longer, которая применяет алгоритм ожидания ((executions**4) + (Kernel.rand * (executions**4) * jitter)) + 2 (сначала около 3 с, затем около 18 с, потом около 83 с и т. д.)

  • :attempts — ставит задачу в очередь указанное число раз (по умолчанию: 5 попыток) или использует ссылку на символ :unlimited, чтобы повторять попытки, пока задача не завершится успешно. В число попыток входит первоначальный запуск задачи.

  • :queue — повторно ставит задачу в другую очередь

  • :priority — повторно ставит задачу в очередь с другим приоритетом

  • :jitter — случайная задержка, добавляемая ко времени ожидания при расчёте интервала между попытками. По умолчанию составляет 15% (0.15) — это верхняя граница возможного времени ожидания (выраженная в процентах)

  • :report — ошибки перед повторной попыткой передаются системе отчётов Rails.error

Примеры

class RemoteServiceJob < ActiveJob::Base
  retry_on CustomAppException # defaults to ~3s wait, 5 attempts
  retry_on AnotherCustomAppException, wait: ->(executions) { executions * 2 }
  retry_on CustomInfrastructureException, wait: 5.minutes, attempts: :unlimited

  retry_on ActiveRecord::Deadlocked, wait: 5.seconds, attempts: 3
  retry_on Net::OpenTimeout, Timeout::Error, wait: :polynomially_longer, attempts: 10 # retries at most 10 times for Net::OpenTimeout and Timeout::Error combined
  # To retry at most 10 times for each individual exception:
  # retry_on Net::OpenTimeout, wait: :polynomially_longer, attempts: 10
  # retry_on Net::ReadTimeout, wait: 5.seconds, jitter: 0.30, attempts: 10
  # retry_on Timeout::Error, wait: :polynomially_longer, attempts: 10

  retry_on YetAnotherCustomAppException, report: true
  retry_on EvenWorseCustomAppException do |job, error|
    CustomErrorHandlingCode.handle(job, error)
  end

  def perform(*args)
    # Might raise CustomAppException, AnotherCustomAppException, or YetAnotherCustomAppException for something domain specific
    # Might raise ActiveRecord::Deadlocked when a local db deadlock is detected
    # Might raise Net::OpenTimeout or Timeout::Error when the remote service is down
  end
end

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API