Class: RedisLocks::Mutex
- Inherits:
-
Object
- Object
- RedisLocks::Mutex
- Defined in:
- lib/redis_locks/mutex.rb
Constant Summary collapse
- NAMESPACE =
"mutex"
Instance Method Summary collapse
-
#initialize(key, expires_in: 86400, redis: RedisLocks.redis) ⇒ Mutex
constructor
A new instance of Mutex.
- #lock(expires_at: nil, &block) ⇒ Object
- #lock!(expires_at: nil, &block) ⇒ Object
- #unlock ⇒ Object
Constructor Details
#initialize(key, expires_in: 86400, redis: RedisLocks.redis) ⇒ Mutex
Returns a new instance of Mutex.
12 13 14 15 16 17 18 |
# File 'lib/redis_locks/mutex.rb', line 12 def initialize(key, expires_in: 86400, redis: RedisLocks.redis) @key = "#{NAMESPACE}:#{key}" @redis = redis @expires_in = expires_in.to_i raise ArgumentError.new("Invalid expires_in: #{expires_in}") unless expires_in > 0 end |
Instance Method Details
#lock(expires_at: nil, &block) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/redis_locks/mutex.rb', line 20 def lock(expires_at: nil, &block) now = Time.now.utc.to_i locked = false if expires_at expires_at = expires_at.to_i else expires_at = now + @expires_in end if @redis.setnx(@key, expires_at) @redis.expire(@key, expires_at - now) @expires_at = expires_at locked = true else # it was locked if (old_value = @redis.get(@key)).to_i <= now # lock has expired if @redis.getset(@key, expires_at) == old_value @expires_at = expires_at locked = true end end end return false unless locked return_or_yield(&block) end |
#lock!(expires_at: nil, &block) ⇒ Object
49 50 51 52 53 |
# File 'lib/redis_locks/mutex.rb', line 49 def lock!(expires_at: nil, &block) locked = lock(expires_at: expires_at) raise AlreadyLocked.new(@key) unless locked return_or_yield(&block) end |
#unlock ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/redis_locks/mutex.rb', line 55 def unlock return unless @expires_at # To prevent deleting a lock acquired from another process, only delete # the key if it's still valid, and will be for another 2 seconds if Time.now.utc.to_i - 2 < @expires_at @redis.del(@key) end @expires_at = nil end |