如何判断Ruby代码是否在Sidekiq作业中执行及实现in_sidekiq_job方法
如何判断Ruby代码是否在Sidekiq作业中执行
当然可以实现这个功能!Sidekiq内部有专门的标识来帮我们检测当前代码的运行上下文,下面给你两种可靠的实现方案:
方案一:利用线程局部变量与Sidekiq内置方法
Sidekiq在执行作业时,会把作业相关的信息存入当前线程的局部变量中,同时也提供了Sidekiq::Worker.current_job方法来获取当前作业对象。你可以这样实现in_sidekiq_job方法:
def in_sidekiq_job # 检查线程局部变量里的Sidekiq作业ID是否存在 Thread.current[:sidekiq_job_id].present? || # 兼容不同Sidekiq版本,先判断常量是否存在再检查当前作业 (defined?(Sidekiq::Worker) && Sidekiq::Worker.current_job.present?) end
小解释:
Thread.current[:sidekiq_job_id]:Sidekiq执行作业时会自动设置这个线程变量,只要它有值,就说明当前代码正运行在Sidekiq作业上下文里。Sidekiq::Worker.current_job:这个方法会返回当前正在执行的Sidekiq作业实例,如果不为空,也能证明是在作业中执行。加上defined?(Sidekiq::Worker)的判断,是为了避免在没有加载Sidekiq的环境中触发未定义常量的错误。
方案二:更简洁的版本(适配Sidekiq 6.x+)
如果你使用的是较新的Sidekiq版本(6.x及以上),可以用更直接的方式判断:
def in_sidekiq_job # 先判断是否在Sidekiq服务进程中,再检查是否有作业执行器 Sidekiq.server? && Thread.current[:sidekiq_executor].present? end
Sidekiq.server?会先确认当前进程是Sidekiq的服务进程,再结合Thread.current[:sidekiq_executor]这个作业执行时设置的变量,就能准确判断是否在作业执行上下文里。
集成到你的示例代码中
把上面的方法整合进去,你的代码就能正常工作了:
def in_sidekiq_job Thread.current[:sidekiq_job_id].present? || (defined?(Sidekiq::Worker) && Sidekiq::Worker.current_job.present?) end def method_for_anyone_to_call if in_sidekiq_job puts "hey! I'm running in a Sidekiq job." else puts "I'm running outside a Sidekiq job." end end
当这个方法在Sidekiq作业里被调用时,就会输出对应的提示;在普通上下文调用时则会显示另一条信息。
内容的提问来源于stack exchange,提问作者Mark Bolusmjak
相关产品推荐
相关产品推荐

