[ruby on rails] ActiveJob中 discard_on,retry_on和 rescue_from的应用

发布于:2025-06-26 ⋅ 阅读:(13) ⋅ 点赞:(0)

job 中 discard_on,retry_on和 rescue_from的应用

# frozen_string_literal: true

class OrdersRefundJob < ApplicationJob
  queue_as :default

  # 不重试了直接丢弃
  discard_on Exceptions::CustomException 

  # ActiveRecord::RecordNotFound 错误的话,间隔 2 秒,重试 3 次
  retry_on ActiveRecord::RecordNotFound, wait: 2.seconds, attempts: 3

  # Exceptions::InvalidAction 错误的话,更新数据
  rescue_from Exceptions::InvalidAction do
    service = AfterSaleService.find(arguments[0])
    service.update!(is_refunding: false)
  end

  def perform(service_id)
    service = AfterSaleService.find(service_id)
    service.refund
  end
end

相关测试

# frozen_string_literal: true

require 'rails_helper'

RSpec.describe OrdersRefundJob, type: :job do
  it 'auto refund the aftersale order' do
    @order = create(:order, :paid)

    expect(@order.status).to eq('paid')
    expect(service.status).to eq('initial')

    OrdersRefundJob.perform_now(service.id)

    expect(@order.reload.status).to eq('closed')
    expect(service.reload.status).to eq('finished')
  end

  it 'retry on ActiveRecord::RecordNotFound' do
    ActiveJob::Base.queue_adapter.enqueued_jobs.clear
    expect do
      OrdersRefundJob.perform_now(nil)
    end.not_to raise_error(ActiveRecord::RecordNotFound)
    expect(enqueued_jobs.size).to eq(1)
    job_detail = enqueued_jobs.find { |job| job[:job] == OrdersRefundJob }
    expect(job_detail).to be_present
  end
end


网站公告

今日签到

点亮在社区的每一天
去签到