Module: Ricordami::IsLockable::InstanceMethods

Defined in:
lib/ricordami/is_lockable.rb

Instance Method Summary collapse

Instance Method Details

#generate_expiration(expiration) ⇒ Object



47
48
49
# File 'lib/ricordami/is_lockable.rb', line 47

def generate_expiration(expiration)
  (Time.now + expiration.to_f).to_f
end

#lock!(options = {}, &block) ⇒ Object

Raises:



10
11
12
13
14
15
16
17
18
19
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
# File 'lib/ricordami/is_lockable.rb', line 10

def lock!(options = {}, &block)
  key           = KeyNamer.lock(self.class, :id => id)
  start         = Time.now
  acquired_lock = false
  expiration    = nil
  expires_in    = options.fetch(:expiration, 15)
  timeout       = options.fetch(:timeout, 1)

  while (Time.now - start) < timeout
    expiration    = generate_expiration(expires_in)
    acquired_lock = redis.setnx(key, expiration)
    break if acquired_lock

    old_expiration = redis.get(key).to_f

    if old_expiration < Time.now.to_f
      expiration     = generate_expiration(expires_in)
      old_expiration = redis.getset(key, expiration).to_f

      if old_expiration < Time.now.to_f
        acquired_lock = true
        break
      end
    end

    sleep 0.1
  end

  raise(LockTimeout.new(key, timeout)) unless acquired_lock

  begin
    yield
  ensure
    redis.del(key) if expiration > Time.now.to_f
  end
end