Class: Redis::Lock

Inherits:
Object
  • Object
show all
Defined in:
lib/redis/lock.rb

Overview

Class representing a lock. This functions like a proxy class, in that you can say @object.lock_name { block } to use the lock and also directly, but it is better to use the lock :foo class method in your class to define a lock.

Defined Under Namespace

Classes: LockTimeout

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key, redis = $redis, options = {}) ⇒ Lock

Returns a new instance of Lock.



13
14
15
16
17
18
19
# File 'lib/redis/lock.rb', line 13

def initialize(key, redis=$redis, options={})
  @key = key
  @redis = redis
  @options = options
  @options[:timeout] ||= 5
  @redis.setnx(key, @options[:start]) unless @options[:start] == 0 || @options[:init] === false
end

Instance Attribute Details

#keyObject (readonly)

Returns the value of attribute key.



12
13
14
# File 'lib/redis/lock.rb', line 12

def key
  @key
end

#optionsObject (readonly)

Returns the value of attribute options.



12
13
14
# File 'lib/redis/lock.rb', line 12

def options
  @options
end

#redisObject (readonly)

Returns the value of attribute redis.



12
13
14
# File 'lib/redis/lock.rb', line 12

def redis
  @redis
end

Instance Method Details

#clearObject Also known as: delete

Clear the lock. Should only be needed if there's a server crash or some other event that gets locks in a stuck state.



23
24
25
# File 'lib/redis/lock.rb', line 23

def clear
  redis.del(key)
end

#lock(&block) ⇒ Object

Get the lock and execute the code block. Any other code that needs the lock (on any server) will spin waiting for the lock up to the :timeout that was specified when the lock was defined.

Raises:



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/redis/lock.rb', line 31

def lock(&block)
  start = Time.now
  gotit = false
  while Time.now - start < @options[:timeout]
    gotit = redis.setnx(key, 1)
    break if gotit
    sleep 0.1
  end
  raise LockTimeout, "Timeout on lock #{key} exceeded #{@options[:timeout]} sec" unless gotit
  begin
    yield
  ensure
    redis.del(key)
  end
end