Class: Bosh::Director::Lock

Inherits:
Object show all
Defined in:
lib/bosh/director/lock.rb

Overview

Distributed lock backed by Redis.

Defined Under Namespace

Classes: TimeoutError

Instance Method Summary collapse

Constructor Details

#initialize(name, opts = {}) ⇒ Lock

Creates new lock with the given name.

Parameters:

  • name

    lock name

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • timeout (Number)

    how long to wait before giving up

  • expiration (Number)

    how long to wait before expiring an old lock



15
16
17
18
19
20
21
22
# File 'lib/bosh/director/lock.rb', line 15

def initialize(name, opts = {})
  @name = name
  @id = SecureRandom.uuid
  @timeout = opts[:timeout] || 1.0
  @expiration = opts[:expiration] || 10.0
  @logger = Config.logger
  @refresh_thread = nil
end

Instance Method Details

#lock {|void| ... } ⇒ void

This method returns an undefined value.

Acquire a lock.

Yields:

  • (void)

    optional block to do work before automatically releasing the lock.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/bosh/director/lock.rb', line 29

def lock
  acquire

  @refresh_thread = Thread.new do
    redis = Config.redis
    sleep_interval = [1.0, @expiration/2].max
    begin
      loop do
        @logger.debug("Renewing lock: #@name")
        redis.watch(@name)
        existing_lock = redis.get(@name)
        lock_id = existing_lock.split(":")[1]
        break if lock_id != @id
        lock_expiration = Time.now.to_f + @expiration + 1
        redis.multi do
          redis.set(@name, "#{lock_expiration}:#@id")
        end
        sleep(sleep_interval)
      end
    ensure
      @logger.debug("Lock renewal thread exiting")
      redis.quit
    end
  end

  if block_given?
    begin
      yield
    ensure
      release
    end
  end
end

#releasevoid

This method returns an undefined value.

Release a lock that was not auto released by the lock method.



66
67
68
69
# File 'lib/bosh/director/lock.rb', line 66

def release
  @refresh_thread.exit if @refresh_thread
  delete
end