跳至內容 跳至搜尋
方法
A
D
R

執行個體公開方法

after_discard(&blk)

工作因任何原因即將被捨棄時執行的區塊。

範例

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

  ...

end
# File activejob/lib/active_job/exceptions.rb, line 124
def after_discard(&blk)
  self.after_discard_procs += [blk]
end

discard_on(*exceptions)

如果引發例外狀況,不重試就捨棄工作。這在工作的主旨(例如 Active Record)不再可用,而工作不再相關時很有用。

你也可以傳遞會被呼叫的區塊。這個區塊傳遞工作執行個體作為第一個參數,並將錯誤執行個體作為第二個參數。

retry_ondiscard_on 處理常式從底部往上搜尋,並往上搜尋類別層級。處理常式第一個類別有 exception.is_a?(klass) 為 true,就會被呼叫(如果有的話)。

範例

class SearchIndexingJob < ActiveJob::Base
  discard_on ActiveJob::DeserializationError
  discard_on(CustomAppException) do |job, error|
    ExceptionNotifier.caught(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
# File activejob/lib/active_job/exceptions.rb, line 103
def discard_on(*exceptions)
  rescue_from(*exceptions) do |error|
    instrument :discard, error: error do
      yield self, error if block_given?
      run_after_discard_procs(error)
    end
  end
end

retry_on(*exceptions, wait: 3.seconds, attempts: 5, queue: nil, priority: nil, jitter: JITTER_DEFAULT)

捕捉例外狀況,重新排程工作重新執行很多秒,針對特定次數嘗試。如果引發例外狀況次數超過指定嘗試次數,例外狀況就會允許上浮至底層佇列系統,這個系統可能有自己的重試機制,或將其放入暫存佇列中以供檢查。

如果重試嘗試失敗以取得自訂邏輯,你也可以傳遞會被呼叫的區塊,而不是讓例外狀況上浮。這個區塊傳遞工作執行個體作為第一個參數,並將錯誤執行個體作為第二個參數。

retry_ondiscard_on 處理常式從底部往上搜尋,並往上搜尋類別層級。處理常式第一個類別有 exception.is_a?(klass) 為 true,就會被呼叫(如果有的話)。

選項

  • :wait - 重新以延遲方式加入工作,指定為秒數(預設:3 秒)、計算程序將執行次數當作參數,或符號參考「:polynomially_longer」,會套用等候演算法「(executions**4)+(Kernel.rand *(executions**4)* jitter)+ 2」。(第一次等待約 3 秒,接著約 18 秒,接著約 83 秒,等等)

  • :attempts - 將工作加入佇列指定次數(預設:5 次嘗試)或符號參考「:unlimited」,在工作成功之前都會重試。嘗試次數包含原始工作的執行。

  • :queue - 重新在不同佇列中加入工作

  • :priority - 重新加入工作時有不同的優先權

  • :jitter - 計算時序間隔時,使用的隨機等待時間延遲。預設值是 15%(0.15),表示可能等待時間的上限(表示為百分比)

範例

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) do |job, error|
    ExceptionNotifier.caught(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
# File activejob/lib/active_job/exceptions.rb, line 62
def retry_on(*exceptions, wait: 3.seconds, attempts: 5, queue: nil, priority: nil, jitter: JITTER_DEFAULT)
  rescue_from(*exceptions) do |error|
    executions = executions_for(exceptions)
    if attempts == :unlimited || executions < attempts
      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