You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在ApplicationJob集成Sidekiq::Job后,如何让around_perform回调生效?

解决Sidekiq Job中around_perform回调未触发的问题

问题根源

你的代码核心问题在于子类重写了perform方法,完全跳过了父类ApplicationJob中包含回调逻辑的perform实现。父类里的perform方法负责触发run_callbacks(:perform),但子类直接覆盖该方法后,回调流程根本没机会执行,导致set_paper_trail_whodunnit永远不会被调用。

解决方案

方案1:遵循父类设计,子类实现perform!而非perform

父类ApplicationJob原本就设计了perform!作为子类需要实现的业务逻辑入口,perform方法专门负责回调的触发。修改子类代码,把业务逻辑移到perform!中:

class ExampleJob < ApplicationJob
  def perform!(record_id)
    Record.find(record_id).update!(column: new_value)
  end
end

这样当Sidekiq调用perform时,会执行父类的perform方法,触发around_perform回调,再调用子类的perform!执行业务逻辑,PaperTrail的whodunnit就能正确设置。

方案2:调整父类逻辑,强制回调触发(不推荐,破坏设计约定)

如果不想修改子类代码,可以在父类中用prepend来确保回调逻辑被执行,但这种方式会增加复杂度,不如方案1简洁:

class ApplicationJob
  include Sidekiq::Job
  extend ActiveModel::Callbacks

  sidekiq_options queue: :default

  define_model_callbacks :perform
  around_perform :set_paper_trail_whodunnit

  def set_paper_trail_whodunnit
    PaperTrail.request.whodunnit = self.class.name
    yield
  ensure
    PaperTrail.request.whodunnit = nil
  end

  # 用prepend确保回调逻辑优先执行
  module PerformCallbackWrapper
    def perform(*args)
      run_callbacks(:perform) do
        super(*args)
      end
    end
  end

  prepend PerformCallbackWrapper

  def perform!(*_args)
    raise NotImplementedError, 'Missing your #perform! method implementation'
  end
end

这样即使子类重写了perform,prepend的模块会先执行回调逻辑,再调用子类的perform方法。

额外说明

  • 如果你想使用Sidekiq原生的回调,可以直接用Sidekiq提供的around_perform钩子(不需要ActiveModel::Callbacks),写法如下:
class ApplicationJob
  include Sidekiq::Job

  sidekiq_options queue: :default
  sidekiq_options around_perform: :set_paper_trail_whodunnit

  def set_paper_trail_whodunnit
    PaperTrail.request.whodunnit = self.class.name
    yield
  ensure
    PaperTrail.request.whodunnit = nil
  end

  def perform(*args)
    perform!(*args)
  end

  def perform!(*_args)
    raise NotImplementedError, 'Missing your #perform! method implementation'
  end
end

这种方式不需要手动处理run_callbacks,Sidekiq会自动触发钩子逻辑,也能避免和ActiveJob的冲突。

内容的提问来源于stack exchange,提问作者Richard Wright

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 04:32:02