Job Control - rselk/sidekiq GitHub Wiki

For slow (long-running) jobs this is a possible technique using throw/catch that can be used to check when Sidekiq is shutting down, and stop cleanly.

In the slow-running class, you can define a helper and use it like this:

class SlowTask

  def process(&control)
    with_control(control) do
      millions_of_records.each do |item|
        do_something(item)
        yield_control      # periodically yield control at a convenient breakpoint
      end
    end
  end

  private

  def with_control(control_callback)
    @control = control_callback
    catch(:stop) do
      yield
    end
  ensure
    @control = nil
  end

  def yield_control
    @control.call if @control
  end
end

In the worker, pass the control block to your task:

class SlowWorker
  def perform(args)
    slow_task = SlowTask.new(args)
    slow_task.process { throw(:stop, "Sidekiq stopping") if Sidekiq::Fetcher.done? }
  end
end