Sandip Mane
by Sandip Mane
1 min read

Categories

  • Rails
  • Sidekiq

Tags

  • rails
  • sidekiq

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 app/workers/base_worker.rb 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

Sidekiq provides perform_async, we can add following helpers around this method.

Use perform_unique_async

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

Use perform_unique_in

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

Use perform_unique_at

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 BaseWorker class

Finally,

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.

And as always, thanks for reading!😃