Class: RedisLocks::Mutex

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

Constant Summary collapse

NAMESPACE =
"mutex"

Instance Method Summary collapse

Constructor Details

#initialize(key, redis:, expires_in: 86400, expires_at: nil) ⇒ Mutex

Returns a new instance of Mutex.



12
13
14
15
16
# File 'lib/redis_locks/mutex.rb', line 12

def initialize(key, redis:, expires_in: 86400, expires_at: nil)
  @key = "#{NAMESPACE}:#{key}"
  @redis = redis
  @expires_at = (expires_at.to_i if expires_at) || (Time.now.utc.to_i + expires_in)
end

Instance Method Details

#lock(&block) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/redis_locks/mutex.rb', line 18

def lock(&block)
  now = Time.now.utc.to_i
  locked = false

  if @redis.setnx(@key, @expires_at)
    @redis.expire(@key, @expires_at - now)
    locked = true
  else # it was locked
    if (old_value = @redis.get(@key)).to_i <= now
      # lock has expired
      if @redis.getset_value(@key, @expires_at) == old_value
        locked = true
      end
    end
  end

  return false unless locked

  return_or_yield(&block)
end

#lock!(&block) ⇒ Object

Raises:



39
40
41
42
43
# File 'lib/redis_locks/mutex.rb', line 39

def lock!(&block)
  locked = lock
  raise AlreadyLocked.new(@key) unless locked
  return_or_yield(&block)
end

#unlockObject

only delete the key if it’s still valid, and will be for another 2 seconds



46
47
48
49
50
# File 'lib/redis_locks/mutex.rb', line 46

def unlock
  if Time.now.utc.to_i - 2 < @expires_at
    @redis.del(@key)
  end
end