In one of the projects I work, there was a requirement to schedule only one job for a record at a time. If someone wants to schedule another one for the same record, the system should clear the old schedule for it and schedule the new one.
To do this, we are going to add some helpers to
using Sidekiq API.
Be careful with the following method when dealing with 10,000+ jobs, you could look at Sidekiq Pro for efficiency.
Add the following helper
This helper deletes the jobs from sheduled set that match with the worker name and the arguments. Tweak the following helper as per the requirements to optimize the performance.
def self.delete_matched(worker_name, arguments) set = Sidekiq::ScheduledSet.new set = if arguments.is_a?(Array) && arguments.first.is_a?(String) set.scan arguments.first elsif arguments.is_a?(String) set.scan arguments else set.scan worker_name end set.each do |job| job.delete if job.display_class == worker_name && job.args == [arguments] end end
we can add following helpers around this method.
This method enqueues a unique job
## # Usage: # HeartbeatsWorker.perform_unique_async(id) # def self.perform_unique_async(*arguments) self.delete_matched(name, arguments) self.perform_async(arguments) end
This method schedules a unique job to be performed in given time.
## # Usage: # HeartbeatsWorker.perform_unique_in(30.seconds, id) # def self.perform_unique_in(t, *arguments) self.delete_matched(name, arguments) self.perform_in(t, arguments) end
This method schedules a unique job to be performed at a given time.
## # Usage: # HeartbeatsWorker.perform_unique_at(datetime, id) # def self.perform_unique_at(t, *arguments) self.delete_matched(name, arguments) self.perform_at(t, arguments) end
Here is the full
In this post, we explored how we could remove duplicate jobs from the Sidekiq’s ScheduledSet and enqueue unique ones. You can dig deeper into the Sidekiq API to customize it as per the needs.