Class: Bosh::Director::Lock

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

Overview

Distributed lock backed by DB.

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
  @uid = 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
# File 'lib/bosh/director/lock.rb', line 29

def lock
  acquire

  @refresh_thread = Thread.new do
    sleep_interval = [1.0, @expiration/2].max
    begin
      stopped = false
      until stopped
        @logger.debug("Renewing lock: #@name")
        lock_expiration = Time.now.to_f + @expiration + 1

        if Models::Lock.where(name: @name, uid: @uid).update(expired_at: Time.at(lock_expiration)) == 0
          stopped = true
        end

        sleep(sleep_interval) unless stopped
      end
    ensure
      @logger.debug("Lock renewal thread exiting")
    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.



63
64
65
66
# File 'lib/bosh/director/lock.rb', line 63

def release
  @refresh_thread.exit if @refresh_thread
  delete
end