class Rudis::Lock

Public Instance Methods

acquire(options={}) { || ... } click to toggle source
# File lib/rudis/structures/lock.rb, line 5
    def acquire(options={})
      options.rmerge!(
        :tries => 1,
        :sleep => 1
      )

      return set(options) unless block_given?

      1.upto options[:tries] do
        if set(options)
          return begin
            yield
          ensure
            clear
          end
        end
        sleep options[:sleep]
      end

      # oops, we couldn't get the lock
      raise LockFailed, <<-msg.squish
        Unable to acquire lock after #{options[:tries]} time(s)
      msg
      return false
    end
set(options={}) click to toggle source

implements the SETNX locking algorithm from code.google.com/p/redis/wiki/SetnxCommand

# File lib/rudis/structures/lock.rb, line 33
def set(options={})
  options.rmerge!(
    :timeout => 30
  )
  if redis.setnx(key, timestamp(options[:timeout]))
    return true
  else
    # check the timestamp
    old = redis.getset(key, timestamp(options[:timeout]))
    if old < timestamp
      # expired lock, we're good
      return true
    else
      # lock is not expired, put it back
      redis.set(key, old)
      return false
    end
  end
end

Private Instance Methods

timestamp(timeout=0) click to toggle source
# File lib/rudis/structures/lock.rb, line 56
def timestamp(timeout=0)
  Time.now.to_i + timeout
end