cvdv
cvdv

Reputation: 2932

Do I need to put everything in app/workers for sidekiq?

I'm currently migrating from DJ to sidekiq and have a lot of plain old ruby objects that I would use like so:

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

I thought I could just move SomeService into the app/workers folder and add include Sidekiq::Worker but it doesn't ever go into the sidekiq queue and just calls performs on the spot

class SomeService
  include Sidekiq::Worker

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

  def perform
    @some_instance.do_something
  end
end

so instead I have to create a sidekiq worker to call the service

class SomeServiceWorker
  include Sidekiq::Worker

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

Is there a way to just use the SomeService, which contains an initialize method and perform method so I don't have to create a worker to call my service object?

Upvotes: 4

Views: 2896

Answers (3)

KSD Putra
KSD Putra

Reputation: 497

These won't be background job:

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

You have to use perform without create the class instance:

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

So, you cannot have initialize method in for sidekiq worker.

Assuming those are your only code, so:

class SomeServiceWorker
  include Sidekiq::Worker

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

If SomeService is actually more complex, the best practice is to do what you do:

class SomeServiceWorker
  include Sidekiq::Worker

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

Upvotes: 0

Aldo Ziflaj
Aldo Ziflaj

Reputation: 13

Sidekiq doesn't care much about where the files are and/or how they are named, as long as they include Sidekiq::Worker. The convention though, is to put all the workers in the app/workers directory and to name them as MyWorker.

You can then call them as:

MyWorker.perform_async params

Upvotes: 1

Andriy Kondzolko
Andriy Kondzolko

Reputation: 822

Only one mistake what you did, you forget to add "Worker" word in your class name in the first file!

class SomeServiceWorker
  include Sidekiq::Worker

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

  def perform
    @some_instance.do_something
  end
end

And this code will run your worker

SomeServiceWorker.new(id).perform

Upvotes: 1

Related Questions