如何在Rails中使用Resque指定默认队列来处理所有作业?

5

我希望所有的enqueue调用都默认使用一个队列,除非另有指定,这样可以使代码更加DRY且易于维护。为了指定一个队列,文档中说要在类内定义一个变量@queue = X。因此,我尝试了以下操作,但它没有起作用,你有什么想法吗?

class ResqueJob
  class << self; attr_accessor :queue end
  @queue = :app
end

class ChildJob < ResqueJob
  def self.perform
  end
end

Resque.enqueue(ChildJob)

Resque::NoQueueError: Jobs must be placed onto a queue.
from /Library/Ruby/Gems/1.8/gems/resque-1.10.0/lib/resque/job.rb:44:in `create'
from /Library/Ruby/Gems/1.8/gems/resque-1.10.0/lib/resque.rb:206:in `enqueue'
from (irb):5

我怀疑你可能没有完全理解文档。除非你在类中明确定义了一个队列(就像你现在这样),否则作业会落在默认队列上。在你的代码中,入队的作业将落在“app”队列上。尝试注释掉@queue = :app并观察界面显示排队的作业。 - Tass
3个回答

11

在 Ruby 中,类变量不会被继承。这就是为什么 Resque 找不到你的 @queue 变量的原因。

你应该在父类中定义 self.queue。Resque 首先检查是否存在 @queue,但其次查找 queue 类方法:

class ResqueJob
  def self.queue; :app; end
end

class ChildJob < ResqueJob
  def self.perform; ...; end
end

4
如果你想使用一个混合器来完成这个操作,你可以按照以下方式进行:
module ResqueJob
  extend ActiveSupport::Concern

  module ClassMethods
    def queue
      @queue || :interactor_operations
    end
  end
end

class ChildJob
  include ResqueJob

  def self.perfom
  end
end

(如果您没有activesupport,也可以使用经典的ruby方式来完成,但我发现这种方法更容易,所以非常值得尝试;))

0

尝试使用mixin。像这样:

module ResqueJob
  def initQueue
    @queue = :app
  end 
end

class ChildJob 
  extend ResqueJob

  initQueue

  def self.perform
  end
end

Resque.enqueue(ChildJob)

Mixins可以工作,但不够简洁。为每个作业类重复这个过程似乎并不是很DRY。 - Kang Chen

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