Is there any way to tell sidekiq that one job is dependent on another and can't be started until latter is finished?
Just using Sidekiq only; the answer would be no. As DickieBoy suggested, you should be able to just kick it off when the dependent job completes. Something like this.
# app/workers/hard_worker.rb
class HardWorker
include Sidekiq::Worker
def perform()
puts 'Doing hard work'
LazyWorker.perform_async()
end
end
# app/workers/lazy_worker.rb
class LazyWorker
include Sidekiq::Worker
def perform(name, count)
puts "Guess it's time I do something"
end
end
Here LazyWorker only runs at the end of HardWorker; additional logic can be added if this is not always needed; LazyWorker can still be called directly if/when needed. This should work for most if not all use cases; and with Sidekiq it is really your only option unless you pull in some other gem.
When firing directly from another job isn't good enough...
If you are doing something where this will not work you should consider a state machine. When a job is fired it would create a record of itself, likely along with an ID, and could have running, failed, completed, waiting states. The dependent job can then easily check for one or more dependencies in the state table and make sure all of it's dependencies are fulfilled.
You're dependent job could do a look up in your state table for the dependency
You can define job dependencies using Sidekiq Superworker:
# config/initializers/superworkers.rb
Superworker.create(:MySuperworker, :user_id) do
Worker1 :user_id
Worker2 :user_id
end
# Anywhere
MySuperworker.perform_async(123)
When you run MySuperworker, Worker1 will start. When it finishes, Worker2 will start. This lets you separate the dependency graph from the workers themselves. (Disclaimer: I'm the gem's author.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With