Class: EM::Hiredis::Lock

Inherits:
Object
  • Object
show all
Defined in:
lib/em-hiredis/lock.rb

Overview

Distributed lock built on redis

Instance Method Summary collapse

Constructor Details

#initialize(redis, key, timeout) ⇒ Lock

Returns a new instance of Lock.



6
7
8
9
10
# File 'lib/em-hiredis/lock.rb', line 6

def initialize(redis, key, timeout)
  @redis, @key, @timeout = redis, key, timeout
  @locked = false
  @expiry = nil
end

Instance Method Details

#acquireObject

Acquire the lock

It is ok to call acquire again before the lock expires, which will attempt to extend the existing lock.

Returns a deferrable which either succeeds if the lock can be acquired, or fails if it cannot. In both cases the expiry timestamp is returned (for the new lock or for the expired one respectively)



17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/em-hiredis/lock.rb', line 17

def acquire
  df = EM::DefaultDeferrable.new
  expiry = new_expiry
  @redis.setnx(@key, expiry) { |setnx|
    if setnx == 1
      lock_acquired(expiry)
      df.succeed(expiry)
    else
      attempt_to_acquire_existing_lock(df)
    end
  }
  return df
end

#clearObject

This should not be used in normal operation - force clear



44
45
46
# File 'lib/em-hiredis/lock.rb', line 44

def clear
  @redis.del(@key)
end

#onexpire(&blk) ⇒ Object



4
# File 'lib/em-hiredis/lock.rb', line 4

def onexpire(&blk); @onexpire = blk; end

#unlockObject

Release the lock



32
33
34
35
36
37
38
39
40
41
# File 'lib/em-hiredis/lock.rb', line 32

def unlock
  EM.cancel_timer(@expire_timer) if @expire_timer
  
  if @locked && Time.now.to_i < @expiry
    EM::Hiredis.logger.debug "Lock: released #{@key}"
    @redis.del(@key)
  else
    EM::Hiredis.logger.debug "Lock: could not release #{@key}"
  end
end