class MultiBackgroundJob::Lock

Class Lock provides access to redis “sorted set” used to control unique jobs

Attributes

digest[R]
lock_id[R]
ttl[R]

Public Class Methods

coerce(value) click to toggle source

Initialize a Lock object from hash

@param value [Hash] Hash with lock properties @return [MultiBackgroundJob::Lock, nil]

# File lib/multi_background_job/lock.rb, line 21
def self.coerce(value)
  return unless value.is_a?(Hash)

  digest = value[:digest] || value['digest']
  lock_id = value[:lock_id] || value['lock_id']
  ttl = value[:ttl] || value['ttl']
  return if [digest, lock_id, ttl].any?(&:nil?)

  new(digest: digest, lock_id: lock_id, ttl: ttl)
end
count(digest, from: 0, to: nil, redis: nil) click to toggle source

Number of locks

@param digest [String] It's the uniq string used to group similar jobs @option [Number] from The begin of set. Default to 0 @option [Number] to The end of set. Default to the timestamp of 1 week from now @return Number the amount of entries that within digest

# File lib/multi_background_job/lock.rb, line 68
def self.count(digest, from: 0, to: nil, redis: nil)
  to ||= Time.now.to_f + MultiBackgroundJob::UniqueJob::VALID_OPTIONS[:timeout]
  caller = ->(conn) { conn.zcount(digest, from, to) }

  if redis
    caller.(redis)
  else
    MultiBackgroundJob.redis_pool.with { |conn| caller.(conn) }
  end
end
flush(digest, redis: nil) click to toggle source

Remove all locks from redis “sorted set”

@param [String] digest It's the uniq string used to group similar jobs

# File lib/multi_background_job/lock.rb, line 50
def self.flush(digest, redis: nil)
  return unless digest

  caller = ->(conn) { conn.del(digest) }

  if redis
    caller.(redis)
  else
    MultiBackgroundJob.redis_pool.with { |conn| caller.(conn) }
  end
end
flush_expired_members(digest, redis: nil) click to toggle source

Remove expired locks from redis “sorted set”

@param [String] digest It's the uniq string used to group similar jobs

# File lib/multi_background_job/lock.rb, line 35
def self.flush_expired_members(digest, redis: nil)
  return unless digest

  caller = ->(redis) { redis.zremrangebyscore(digest, '-inf', "(#{now}") }

  if redis
    caller.(redis)
  else
    MultiBackgroundJob.redis_pool.with { |conn| caller.(conn) }
  end
end
new(digest:, lock_id:, ttl:) click to toggle source

@param :digest [String] It's the uniq string used to group similar jobs @param :lock_id [String] The uniq job id @param :ttl [Float] The timestamp related lifietime of the lock before being discarded.

# File lib/multi_background_job/lock.rb, line 11
def initialize(digest:, lock_id:, ttl:)
  @digest = digest
  @lock_id = lock_id
  @ttl = ttl
end
now() click to toggle source

@return [Float] A float timestamp of current time

# File lib/multi_background_job/lock.rb, line 88
def self.now
  Time.now.to_f
end

Public Instance Methods

==(other)
Alias for: eql?
eql?(other) click to toggle source
# File lib/multi_background_job/lock.rb, line 124
def eql?(other)
  return false unless other.is_a?(self.class)

  [digest, lock_id, ttl] == [other.digest, other.lock_id, other.ttl]
end
Also aliased as: ==
lock() click to toggle source

Adds lock_id lock to redis @return [Boolean] Returns true when it's a fresh lock or false when lock already exists

# File lib/multi_background_job/lock.rb, line 102
def lock
  MultiBackgroundJob.redis_pool.with do |conn|
    conn.zadd(digest, ttl, lock_id)
  end
end
locked?() click to toggle source

Check if the lock_id lock exist @return [Boolean] true or false when lock exist or not

# File lib/multi_background_job/lock.rb, line 110
def locked?
  locked = false

  MultiBackgroundJob.redis_pool.with do |conn|
    timestamp = conn.zscore(digest, lock_id)
    return false unless timestamp

    locked = timestamp >= now
    self.class.flush_expired_members(digest, redis: conn)
  end

  locked
end
to_hash() click to toggle source
# File lib/multi_background_job/lock.rb, line 79
def to_hash
  {
    'ttl' => ttl,
    'digest' => (digest.to_s if digest),
    'lock_id' => (lock_id.to_s if lock_id),
  }
end
unlock() click to toggle source

Remove lock_id lock from redis @return [Boolean] Returns true when it's locked or false when there is no lock

# File lib/multi_background_job/lock.rb, line 94
def unlock
  MultiBackgroundJob.redis_pool.with do |conn|
    conn.zrem(digest, lock_id)
  end
end

Protected Instance Methods

now() click to toggle source
# File lib/multi_background_job/lock.rb, line 133
def now
  self.class.now
end