Rails ActiveJob - 如何在 before_enqueue 中停止任务被加入队列

7

我正在运行Rails 4.2.8,希望我的任务只在特定条件下运行。目前,我正在调用作业的代码中进行检查,但将逻辑包含在作业类中会更加清晰。有人这样做过吗?

class MyJob < ApplicationJob
  before_enqueue do |job|
    # check and stop job from being enqueued under certain conditions
  end
  def perform(args*)
    # code here
  end
end

我正在使用 Sidekiq 4.2.10 作为后台任务适配器。

2个回答

9
你可以使用 around_enqueue 来实现相同的结果,而不会抛出异常。当你的任务不需要入队时,这将非常有用。

例如:

around_enqueue do |_job, block|
   if my_condition 
      block.call # this will enqueue your job
   end
end

注意:这个答案是基于Rails 5的ActiveJob代码,但也必须在Rails 4上工作。


我认为使用around_enqueue是在将作业添加到队列之前取消作业的唯一选择。我尝试过使用before_enqueue与discard_on结合使用,但它没有起作用。异常没有被捕获,并且它停止了正在将作业加入队列的进程中代码的执行。 - mario199

1

1
我尝试在before_enqueue中引发异常并使用discard_on,但它没有起作用。异常没有被捕获,而且它停止了代码的执行。所以你的解决方案@Sergio不起作用。如果在before_perform回调中引发异常,则引发异常并且丢弃将起作用。这可能是因为before_enqueue在同一进程中运行,该进程已将作业排队,而before_perform在sidekiq工作程序中运行。 - mario199
@Adeynack :abort 不是一个异常。 - Sergio Tulentsev
在 Ruby 中,它是这样的。异常是符号。请参阅 https://coderwall.com/p/lhkkug/don-t-confuse-ruby-s-throw-statement-with-raise - Adeynack
@Adeynack:感谢您指出这一点。不过,自2014年以来,这些东西显然已经发生了变化 :) - Sergio Tulentsev
2
@Adeynack:没错,那听起来更像了。:+1: - Sergio Tulentsev
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接