- A
- D
- R
实例公共方法
after_discard(&blk) 链接
当作业即将因任何原因被丢弃时运行的代码块。
示例
class WorkJob < ActiveJob::Base
after_discard do |job, exception|
ExceptionNotifier.report(exception)
end
...
end
来源:显示 | 在 GitHub 上
# File activejob/lib/active_job/exceptions.rb, line 130 def after_discard(&blk) self.after_discard_procs += [blk] end
discard_on(*exceptions) 链接
如果抛出异常,则丢弃作业,不尝试重试。当作业的主题(如 Active Record)不再可用,并且作业不再相关时,这很有用。
您也可以传递一个将被调用的代码块。此代码块将使用作业实例作为第一个参数和错误实例作为第二个参数进行调用。
‘retry_on` 和 `discard_on` 处理程序从下到上搜索,并向上遍历类层次结构。对于第一个 exception.is_a?(klass)
为真的类,其处理程序将被调用(如果有)。
示例
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
来源:显示 | 在 GitHub 上
# File activejob/lib/active_job/exceptions.rb, line 109 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_on` 和 `discard_on` 处理程序从下到上搜索,并向上遍历类层次结构。对于第一个 exception.is_a?(klass)
为真的类,其处理程序将被调用(如果有)。
选项
-
: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
来源:显示 | 在 GitHub 上
# 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) if wait == :exponentially_longer ActiveJob.deprecator.warn(<<~MSG.squish) `wait: :exponentially_longer` will actually wait polynomially longer and is therefore deprecated. Prefer `wait: :polynomially_longer` to avoid confusion and keep the same behavior. MSG end 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