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.



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

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)



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

def acquire
  df = EM::DefaultDeferrable.new
  expiry = new_expiry
  @redis.setnx(@key, expiry).callback { |setnx|
    if setnx == 1
      lock_acquired(expiry)
      EM::Hiredis.logger.debug "#{to_s} Acquired new lock"
      df.succeed(expiry)
    else
      attempt_to_acquire_existing_lock(df)
    end
  }.errback { |e|
    df.fail(e)
  }
  return df
end

#activeObject

Lock has been acquired and we’re within it’s expiry time



51
52
53
# File 'lib/em-hiredis/lock.rb', line 51

def active
  @locked && Time.now.to_i < @expiry
end

#clearObject

This should not be used in normal operation - force clear



56
57
58
# File 'lib/em-hiredis/lock.rb', line 56

def clear
  @redis.del(@key)
end

#onexpire(&blk) ⇒ Object

Register an callback which will be called 1s before the lock expires



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

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

#to_sObject



60
61
62
# File 'lib/em-hiredis/lock.rb', line 60

def to_s
  "[lock #{@key}]"
end

#unlockObject

Release the lock

Returns a deferrable



38
39
40
41
42
43
44
45
46
47
48
# File 'lib/em-hiredis/lock.rb', line 38

def unlock
  EM.cancel_timer(@expire_timer) if @expire_timer
  
  unless active
    df = EM::DefaultDeferrable.new
    df.fail Error.new("Cannot unlock, lock not active")
    return df
  end

  @redis.del(@key)
end