Class: Cash::Lock

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

Defined Under Namespace

Classes: Error

Constant Summary collapse

INITIAL_WAIT =
1
DEFAULT_RETRY =
5
DEFAULT_EXPIRY =
30

Instance Method Summary collapse

Constructor Details

#initialize(cache) ⇒ Lock

Returns a new instance of Lock.



9
10
11
# File 'lib/cash/lock.rb', line 9

def initialize(cache)
  @cache = cache
end

Instance Method Details

#acquire_lock(key, lock_expiry = DEFAULT_EXPIRY, retries = DEFAULT_RETRY, initial_wait = INITIAL_WAIT) ⇒ Object

Raises:



26
27
28
29
30
31
32
33
34
# File 'lib/cash/lock.rb', line 26

def acquire_lock(key, lock_expiry = DEFAULT_EXPIRY, retries = DEFAULT_RETRY, initial_wait = INITIAL_WAIT)
  retries.times do |count|
    response = @cache.add("lock/#{key}", Process.pid, lock_expiry)
    return if response == "STORED\r\n"
    raise Error if count == retries - 1
    exponential_sleep(count, initial_wait) unless count == retries - 1
  end
  raise Error, "Couldn't acquire memcache lock for: #{key}"
end

#exponential_sleep(count, initial_wait) ⇒ Object



40
41
42
# File 'lib/cash/lock.rb', line 40

def exponential_sleep(count, initial_wait)
  sleep((2**count) / initial_wait)
end

#release_lock(key) ⇒ Object



36
37
38
# File 'lib/cash/lock.rb', line 36

def release_lock(key)
  @cache.delete("lock/#{key}")
end

#synchronize(key, lock_expiry = DEFAULT_EXPIRY, retries = DEFAULT_RETRY, initial_wait = INITIAL_WAIT) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/cash/lock.rb', line 13

def synchronize(key, lock_expiry = DEFAULT_EXPIRY, retries = DEFAULT_RETRY, initial_wait = INITIAL_WAIT)
  if recursive_lock?(key)
    yield
  else
    acquire_lock(key, lock_expiry, retries, initial_wait)
    begin
      yield
    ensure
      release_lock(key)
    end
  end
end