Class: ZK::Locker::Semaphore

Inherits:
LockerBase show all
Defined in:
lib/zk/locker/semaphore.rb

Overview

A semaphore implementation

Class Attribute Summary collapse

Attributes inherited from LockerBase

#lock_path

Instance Method Summary collapse

Methods inherited from LockerBase

#assert, #interrupt!, #lock!, #lock_basename, #locked?, #unlock, #unlock!, #with_lock

Methods included from ZK::Logger

#logger, wrapped_logger, wrapped_logger=

Constructor Details

#initialize(client, name, semaphore_size, root_node = nil) ⇒ Semaphore

Returns a new instance of Semaphore.


13
14
15
16
17
18
19
20
21
# File 'lib/zk/locker/semaphore.rb', line 13

def initialize(client, name, semaphore_size, root_node=nil)
  raise ZK::Exceptions::BadArguments, <<-EOMESSAGE unless semaphore_size.kind_of? Integer
    semaphore_size must be Integer, not #{semaphore_size.inspect}
  EOMESSAGE

  @semaphore_size = semaphore_size

  super(client, name, root_node || ::ZK::Locker::Semaphore.default_root_node)
end

Class Attribute Details

.default_root_nodeObject

the default root path we will use when a value is not given to a constructor


10
11
12
# File 'lib/zk/locker/semaphore.rb', line 10

def default_root_node
  @default_root_node
end

Instance Method Details

#acquirable?Object

Note:

It should be obvious, but there is no way to guarantee that between the time this method checks the server and taking any action to acquire the lock, another client may grab the lock before us (or converseley, another client may release the lock). This is simply meant as an advisory, and may be useful in some cases.

  • If this instance holds the lock is true we return true (as we have already succeeded in acquiring the lock)
  • If this instance doesn't hold the lock, we'll do a check on the server to see if there are any participants who hold the lock and would prevent us from acquiring the lock.
    • If this instance could acquire the lock we will return true.
    • If another client would prevent us from acquiring the lock, we return false.

44
45
46
47
48
49
50
# File 'lib/zk/locker/semaphore.rb', line 44

def acquirable?
  return true   if locked?
  return false  if blocked_by_semaphore?
  true
rescue Exceptions::NoNode
  true
end

#assert!Object

This is for users who wish to check that the assumption is correct that they actually still hold the lock. (check for session interruption, perhaps a lock is obtained in one method and handed to another)

This, unlike LockerBase#locked? will actually go and check the conditions that constitute "holding the lock" with the server.

checks that we:

  • we have obtained the lock (i.e. LockerBase#locked? is true)
  • have a lock path
  • our lock path still exists
  • there are no exclusive locks with lower numbers than ours

Examples:


def process_jobs
  @lock.with_lock do
    @jobs.each do |j| 
      @lock.assert!
      perform_job(j)
    end
  end
end

def perform_job(j)
  puts "hah! he thinks we're workin!"
  sleep(60)
end

Raises:


39
40
41
# File 'lib/zk/locker/semaphore.rb', line 39

def assert!
  super
end

#blocked_by_semaphore?Boolean

Returns:

  • (Boolean)

52
53
54
# File 'lib/zk/locker/semaphore.rb', line 52

def blocked_by_semaphore?
  ( blocking_locks.size >= @semaphore_size )
end

#got_semaphore?Boolean Also known as: got_lock?

Returns:

  • (Boolean)

71
72
73
# File 'lib/zk/locker/semaphore.rb', line 71

def got_semaphore?
  synchronize { lock_path and not blocked_by_semaphore? }
end

#lock(blocking = false) ⇒ true, ... #lock(opts = {}) ⇒ true, ...

obtain a shared lock.

Overloads:

  • #lock(blocking = false) ⇒ true, ...
    Deprecated.

    in favor of the options hash style

    Parameters:

    • blocking (true, false) (defaults to: false)

      if true we block the caller until we can obtain a lock on the resource

  • #lock(opts = {}) ⇒ true, ...

    Options Hash (opts):

    • :wait (true, false, Numeric) — default: false

      If true we block the caller until we obtain a lock on the resource. If false, we do not block. If a Numeric, the number of seconds we should wait for the lock to be acquired. Will raise LockWaitTimeoutError if we exceed the timeout.

    Since:

    • 1.7

Returns:

  • (true)

    if we're already obtained a shared lock, or if we were able to obtain the lock in non-blocking mode.

  • (false)

    if we did not obtain the lock in non-blocking mode

  • (void)

    if we obtained the lock in blocking mode.

Raises:

  • (InterruptedSession)

    raised when blocked waiting for a lock and the underlying client's session is interrupted.

  • (LockWaitTimeoutError)

    if the given timeout is exceeded waiting for the lock to be acquired

See Also:


26
27
28
# File 'lib/zk/locker/semaphore.rb', line 26

def lock(opts={})
  super
end