class Sidetiq::Lock::Redis

Attributes

key[R]
timeout[R]

Public Class Methods

all() click to toggle source
# File lib/sidetiq/lock/redis.rb, line 8
def self.all
  Sidekiq.redis do |redis|
    redis.keys("sidetiq:*:lock").map do |key|
      new(key)
    end
  end
end
new(key, timeout = Sidetiq.config.lock_expire) click to toggle source
# File lib/sidetiq/lock/redis.rb, line 16
def initialize(key, timeout = Sidetiq.config.lock_expire)
  @key = extract_key(key)
  @timeout = timeout
end

Public Instance Methods

lock() click to toggle source
# File lib/sidetiq/lock/redis.rb, line 54
def lock
  Sidekiq.redis do |redis|
    acquired = false

    watch(redis, key) do
      if !redis.exists(key)
        acquired = !!redis.multi do |multi|
          meta = MetaData.for_new_lock(key)
          multi.psetex(key, timeout, meta.to_json)
        end
      end
    end

    acquired
  end
end
meta_data() click to toggle source
# File lib/sidetiq/lock/redis.rb, line 48
def meta_data
  @meta_data ||= Sidekiq.redis do |redis|
    MetaData.from_json(redis.get(key))
  end
end
stale?() click to toggle source
# File lib/sidetiq/lock/redis.rb, line 38
def stale?
  pttl = meta_data.pttl

  # Consider PTTL of -1 (never set) and larger than the
  # configured lock_expire as invalid. Locks with timestamps
  # older than 1 minute are also considered stale.
  pttl < 0 || pttl >= Sidetiq.config.lock_expire ||
    meta_data.timestamp < (Sidetiq.clock.gettime.to_i - 60)
end
synchronize() { |redis| ... } click to toggle source
# File lib/sidetiq/lock/redis.rb, line 21
def synchronize
  Sidekiq.redis do |redis|
    acquired = lock

    if acquired
      debug "Lock: #{key}"

      begin
        yield redis
      ensure
        unlock
        debug "Unlock: #{key}"
      end
    end
  end
end
unlock() click to toggle source
# File lib/sidetiq/lock/redis.rb, line 71
def unlock
  Sidekiq.redis do |redis|
    watch(redis, key) do
      if meta_data.owner == Sidetiq::Lock::MetaData::OWNER
        redis.multi do |multi|
          multi.del(key)
        end

        true
      else
        false
      end
    end
  end
end
unlock!() click to toggle source
# File lib/sidetiq/lock/redis.rb, line 87
def unlock!
  Sidekiq.redis do |redis|
    redis.del(key)
  end
end

Private Instance Methods

extract_key(key) click to toggle source
# File lib/sidetiq/lock/redis.rb, line 95
def extract_key(key)
  case key
  when Class
    "sidetiq:#{key.name}:lock"
  when String
    key.match(/sidetiq:(.+):lock/) ? key : "sidetiq:#{key}:lock"
  end
end
watch(redis, *args) { || ... } click to toggle source
# File lib/sidetiq/lock/redis.rb, line 104
def watch(redis, *args)
  redis.watch(*args)

  begin
    yield
  ensure
    redis.unwatch
  end
end