class SidekiqUniqueJobs::BatchDelete

Class BatchDelete provides batch deletion of digests

@author Mikael Henriksson <mikael@mhenrixon.com>

Constants

BATCH_SIZE

@return [Integer] the default batch size

SUFFIXES

@return [Array<String>] Supported key suffixes

Attributes

conn[R]

@!attribute [r] conn

@return [Redis, RedisConnection, ConnectionPool] a redis connection
digests[R]

@!attribute [r] digests

@return [Array<String>] a collection of digests to be deleted

Public Class Methods

call(digests, conn = nil) click to toggle source

Executes a batch deletion of the provided digests

@param [Array<String>] digests the digests to delete @param [Redis] conn the connection to use for deletion

@return [void]

# File lib/sidekiq_unique_jobs/batch_delete.rb, line 47
def self.call(digests, conn = nil)
  new(digests, conn).call
end
new(digests, conn) click to toggle source

Initialize a new batch delete instance

@param [Array<String>] digests the digests to delete @param [Redis] conn the connection to use for deletion

# File lib/sidekiq_unique_jobs/batch_delete.rb, line 57
def initialize(digests, conn)
  @count   = 0
  @digests = digests
  @conn    = conn
  @digests ||= []
  @digests.compact!
  redis_version # Avoid pipelined calling redis_version and getting a future.
end

Public Instance Methods

call() click to toggle source

Executes a batch deletion of the provided digests @note Just wraps batch_delete to be able to provide no connection

# File lib/sidekiq_unique_jobs/batch_delete.rb, line 71
def call
  return log_info("Nothing to delete; exiting.") if digests.none?

  log_info("Deleting batch with #{digests.size} digests")
  return batch_delete(conn) if conn

  redis { |rcon| batch_delete(rcon) }
end

Private Instance Methods

batch_delete(conn) click to toggle source

Does the actual batch deletion

@return [Integer] the number of deleted digests

# File lib/sidekiq_unique_jobs/batch_delete.rb, line 88
def batch_delete(conn)
  digests.each_slice(BATCH_SIZE) do |chunk|
    conn.pipelined do
      chunk.each do |digest|
        del_digest(conn, digest)
        conn.zrem(SidekiqUniqueJobs::DIGESTS, digest)
        @count += 1
      end
    end
  end

  @count
end
del_digest(conn, digest) click to toggle source
# File lib/sidekiq_unique_jobs/batch_delete.rb, line 102
def del_digest(conn, digest)
  removable_keys = keys_for_digest(digest)

  if VersionCheck.satisfied?(redis_version, ">= 4.0.0")
    conn.unlink(*removable_keys)
  else
    conn.del(*removable_keys)
  end
end
keys_for_digest(digest) click to toggle source
# File lib/sidekiq_unique_jobs/batch_delete.rb, line 112
def keys_for_digest(digest)
  [digest, "#{digest}:RUN"].each_with_object([]) do |key, digest_keys|
    digest_keys.concat([key])
    digest_keys.concat(SUFFIXES.map { |suffix| "#{key}:#{suffix}" })
  end
end
redis_version() click to toggle source
# File lib/sidekiq_unique_jobs/batch_delete.rb, line 119
def redis_version
  @redis_version ||= SidekiqUniqueJobs.config.redis_version
end