Rails: Cancelling a scheduled job in Sidekiq

那年仲夏 提交于 2019-11-29 00:10:53
Mike Perham

The API documentation has an overview of what you can do but you really need to dive into the source to discover all the capabilities.

You can do this but it won't be efficient. It's a linear scan for find a scheduled job by JID.

require 'sidekiq/api'
Sidekiq::ScheduledSet.new.find_job(jid).try(:delete)

Alternatively your job can look to see if it's still relevant when it runs.

The pseudocode that you wrote should work, though I'd remove the if/else block. Sidekiq::Status.cancel will simply return false if the item was not found. So the following pseudocode should be fine:

1) Cancel scheduled_job_id if scheduled_job_id.present?

2) Run NotifierWorker.perform_at ... - this is done regardless of whether you cancel or not anyway.

However, I will note, as @mike-perham stated, it will be slow (a linear search). As such, when I implemented Sidekiq::Status.cancel I added an optional second parameter for the timestamp. If you pass a timestamp then Redis will find scheduled tasks matching that time using binary search, so it only has to search linearly among the items scheduled at the exact same time.

As such, when cancelling you should run:

Sidekiq::Status.cancel(self.scheduled_job_id, self.release_time_was)

Use a UUID saved in a DB or cache to make sure that you still need to run a job.

class SmartWorker
  include Sidekiq::Worker
  sidekiq_options :queue => :low,
                  :retry => false,
                  :backtrace => false

  def self.schedule id
    uuid = SecureRandom.uuid
    Redis.new.set("#{id}-key", uuid)
    SmartWorker.perform_in(1.minute, id, uuid)
  end

  def perform(id, uuid, force=false)
    return unless uuid == Redis.new.get("#{id}-key")
    if force || CronLockService.lock("lock", 5000)
      begin
        Model.find(id).relation.find_each{|it|
          Service.do_it(it)
        }
      ensure
        CronLockService.expire("lock")
      end
    end
  end
end

So if this happened, it would only run once

SmartWorker.schedule 1    
SmartWorker.schedule 1
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!