Class: SimpleRedisLock::SimpleLock

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

Instance Method Summary collapse

Constructor Details

#initialize(redis = Redis.new) ⇒ SimpleLock

Returns a new instance of SimpleLock.



16
17
18
# File 'lib/simple_redis_lock.rb', line 16

def initialize(redis = Redis.new)
  @redis = redis
end

Instance Method Details

#acquired_at(key) ⇒ Object

time



65
66
67
68
69
70
# File 'lib/simple_redis_lock.rb', line 65

def acquired_at(key)
  time_string = @redis.get("SimpleRedisLock:#{key}")
  return nil unless time_string

  Time.strptime(time_string, '%Y-%m-%d %H:%M:%S.%L %z')
end

#lock(key, expiration) ⇒ Object

Tries to acquire a lock using redis and execute the given block. if lock was acquired

when a block was given, it will execute the given block.
when no block given it will hold the lock until [release] is called.

if lock cannot be acquired, given block.

Returns:

if lock was acquired, the returned value of the given block or [true] if no block given. if lock cannot be acquired, nil is returned

Locks on a key using redis SET NX|EX/PX. Lock will be released when:

1. Block execution completed
2. Block raise an exception
3. Expiration reached

Parameters:

key

The key of the lock, two threads/processes should use the same key.

expiration

Expiration to release the lock, useful when using sidekiq/rescue workers that can be just killed. expected value is in seconds, milliseconds are accepted as float. 0.001 is 1ms. The lock will be released by the [expiration] interval.

block:

A block to be executed when lock is acquired.


45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/simple_redis_lock.rb', line 45

def lock(key, expiration)
  timeout = (expiration * 1000).to_i
  if @redis.set("SimpleRedisLock:#{key}", Time.now.strftime('%Y-%m-%d %H:%M:%S.%L %z'), nx: true, px: timeout)
    if block_given?
      begin
        yield
      ensure
        release key
      end
    else
      true
    end
  end
end

#release(key) ⇒ Object



60
61
62
# File 'lib/simple_redis_lock.rb', line 60

def release(key)
  @redis.del "SimpleRedisLock:#{key}"
end

#ttl(key) ⇒ Object

remaining time till lock expiration



73
74
75
76
77
78
# File 'lib/simple_redis_lock.rb', line 73

def ttl(key)
  pttl = @redis.pttl("SimpleRedisLock:#{key}")
  return nil if pttl == -2

  pttl.to_f / 1000
end