我是否需要将所有内容都放在app / workers中以进行sidekiq?

时间:2019-04-24 20:37:55

标签: ruby-on-rails ruby sidekiq

我目前正从DJ迁移到sidekiq,并且有很多普通的旧红宝石对象,我会这样使用:

Delayed::Job.enqueue(SomeService.new(id))

我以为我可以将SomeService移到app/workers文件夹中并添加include Sidekiq::Worker,但是它从来没有进入sidekiq队列,只是当场执行呼叫

class SomeService
  include Sidekiq::Worker

  def initialize(id)
    @some_instance = SomeClass.find_by(id: id)
  end 

  def perform
    @some_instance.do_something
  end
end

所以相反,我必须创建一个sidekiq worker来调用服务

class SomeServiceWorker
  include Sidekiq::Worker

  def perform(id)
    SomeService.new(id).perform
  end
end

有没有办法只使用SomeService,它包含一个initialize方法和perform方法,所以我不必创建一个工作程序来调用我的服务对象?

3 个答案:

答案 0 :(得分:1)

您所做的只有一个错误,您忘记在第一个文件的类名中添加“ Worker”一词!

class SomeServiceWorker
  include Sidekiq::Worker

  def initialize(id)
    @some_instance = SomeClass.find_by(id: id)
  end 

  def perform
    @some_instance.do_something
  end
end

此代码将使您的工作人员正常运行

SomeServiceWorker.new(id).perform

答案 1 :(得分:1)

Sidekiq不太关心文件的位置和/或命名方式,只要它们包含Sidekiq::Worker。但是,惯例是将所有工作程序放在app/workers目录中,并将其命名为MyWorker

然后可以将其称为:

MyWorker.perform_async params

答案 2 :(得分:0)

这些将不是后台工作:

# This won't do
SomeWorker.new(*args).perform
# This is also won't do
SomeWorker.new.perform(*args)

您必须使用perform而不创建类实例:

# This is correct:
SomeWorker.perform_async(*args)
# This is also correct:
Sidekiq::Client.push('class' => SomeWorker, 'args' => *args)

因此,您不能在sidekiq worker中使用initialize方法。

假设这是您唯一的代码,所以:

class SomeServiceWorker
  include Sidekiq::Worker

  def perform(id)
    some_instance = SomeClass.find(id)
    some_instance.do_something
  end
end

如果SomeService实际上更复杂,则最佳实践是按照自己的意愿做:

class SomeServiceWorker
  include Sidekiq::Worker

  def perform(id)
    SomeService.new(id).perform
  end
end