class Sidekiq::QuickDebounce

Constants

CANCEL_EXPIRATION_BUFFER
VERSION

Private Class Methods

cancel!(conn:, jid:, expires_at:) click to toggle source
# File lib/sidekiq/quick_debounce.rb, line 86
def cancel!(conn:, jid:, expires_at:)
  conn.setex(cancel_namespace_key(jid), expires_at.to_i - Time.now.to_i, 1)
end
cancel_namespace_key(key) click to toggle source
# File lib/sidekiq/quick_debounce.rb, line 92
def cancel_namespace_key(key)
  "sidekiq_quick_debounce:cancelled:#{key}"
end
cancelled?(jid:) click to toggle source
# File lib/sidekiq/quick_debounce.rb, line 82
def cancelled?(jid:)
  Sidekiq.redis { |conn| conn.exists(cancel_namespace_key(jid)) }
end

Public Instance Methods

call(worker, msg, _queue, redis_pool = nil) { || ... } click to toggle source
# File lib/sidekiq/quick_debounce.rb, line 7
def call(worker, msg, _queue, redis_pool = nil)
  @worker = worker.is_a?(String) ? worker.constantize : worker
  @msg = msg

  return yield unless quick_debounce?

  block = proc do |conn|
    fetch_current_options(conn)
    if current_jid
      self.class.cancel!(
        conn: conn,
        jid: current_jid,
        expires_at: current_runs_at + CANCEL_EXPIRATION_BUFFER,
      )
    end
    jid = yield
    update_options(conn, jid['jid'], @msg['at'])
    jid
  end

  if redis_pool
    redis_pool.with(&block)
  else
    Sidekiq.redis(&block)
  end
end

Private Instance Methods

current_jid() click to toggle source
# File lib/sidekiq/quick_debounce.rb, line 62
def current_jid
  @options['jid']
end
current_runs_at() click to toggle source
# File lib/sidekiq/quick_debounce.rb, line 66
def current_runs_at
  Time.at(@options['runs_at']) if @options['runs_at']
end
delayed?() click to toggle source
# File lib/sidekiq/quick_debounce.rb, line 77
def delayed?
  !@msg['at'].nil?
end
fetch_current_options(conn) click to toggle source
# File lib/sidekiq/quick_debounce.rb, line 55
def fetch_current_options(conn)
  @options ||= begin
    options = conn.get(worker_key)
    options ? JSON.parse(options) : {}
  end
end
quick_debounce?() click to toggle source
# File lib/sidekiq/quick_debounce.rb, line 36
def quick_debounce?
  (delayed? && quick_debounce_options) || false
end
quick_debounce_options() click to toggle source
# File lib/sidekiq/quick_debounce.rb, line 40
def quick_debounce_options
  @quick_debounce_options ||= @worker.get_sidekiq_options['quick_debounce']
end
update_options(conn, jid, runs_at) click to toggle source
# File lib/sidekiq/quick_debounce.rb, line 44
def update_options(conn, jid, runs_at)
  # Don't debounce next job if current job is running right now
  return if runs_at <= Time.now.to_f

  conn.setex(
    worker_key,
    runs_at.to_i - Time.now.to_i,
    { jid: jid, runs_at: runs_at }.to_json,
  )
end
worker_key() click to toggle source
# File lib/sidekiq/quick_debounce.rb, line 70
def worker_key
  @worker_key ||= begin
    hash = Digest::MD5.hexdigest(@msg['args'].to_json)
    "sidekiq_quick_debounce:#{@worker.name}:#{hash}"
  end
end