Class: PgLock

Inherits:
Object
  • Object
show all
Defined in:
lib/pg_lock.rb,
lib/pg_lock/locket.rb,
lib/pg_lock/version.rb

Defined Under Namespace

Classes: Locket, UnableToLockError

Constant Summary collapse

PG_LOCK_SPACE =
-2147483648
DEFAULT_CONNECTION_CONNECTOR =
Proc.new do
  if defined?(DEFAULT_CONNECTION)
    DEFAULT_CONNECTION
  elsif defined?(ActiveRecord::Base)
    ActiveRecord::Base.connection.raw_connection
  else
    false
  end
end
DEFAULT_LOGGER =
Proc.new do
  defined?(DEFAULT_LOG) ? DEFAULT_LOG : false
end
UnableToLock =
UnableToLockError
NO_LOCK =
Object.new
VERSION =
"0.2.1"

Instance Method Summary collapse

Constructor Details

#initialize(name:, attempts: 3, attempt_interval: 1, ttl: 60, connection: DEFAULT_CONNECTION_CONNECTOR.call, log: DEFAULT_LOGGER.call, return_result: true) ⇒ PgLock

Returns a new instance of PgLock.


31
32
33
34
35
36
37
38
39
40
41
# File 'lib/pg_lock.rb', line 31

def initialize(name:, attempts: 3, attempt_interval: 1, ttl: 60, connection: DEFAULT_CONNECTION_CONNECTOR.call, log: DEFAULT_LOGGER.call, return_result: true)
  self.name               = name
  self.max_attempts       = [attempts, 1].max
  self.attempt_interval   = attempt_interval
  self.ttl                = ttl || 0 # set this to 0 to disable the timeout
  self.log                = log
  self.return_result      = return_result

  connection or raise "Must provide a valid connection object"
  self.locket             = Locket.new(connection, [PG_LOCK_SPACE, key(name)])
end

Instance Method Details

#aquired?Boolean Also known as: has_lock?

Returns:

  • (Boolean)

82
83
84
# File 'lib/pg_lock.rb', line 82

def aquired?
  locket.active?
end

#createObject


59
60
61
62
63
64
65
66
67
68
69
# File 'lib/pg_lock.rb', line 59

def create
  max_attempts.times.each do |attempt|
    if locket.lock
      log.call(at: :create, attempt: attempt, args: locket.args, pg_lock: true) if log
      return self
    else
      return false if attempt.next == max_attempts
      sleep attempt_interval
    end
  end
end

#deleteObject


71
72
73
74
75
76
77
78
79
80
# File 'lib/pg_lock.rb', line 71

def delete
  locket.unlock
  log.call(at: :delete, args: locket.args, pg_lock: true ) if log
rescue => e
  if log
    log.call(at: :exception, exception: e, pg_lock: true )
  else
    raise e
  end
end

#lock(&block) ⇒ Object

Runs the given block if an advisory lock is able to be acquired.


44
45
46
47
48
# File 'lib/pg_lock.rb', line 44

def lock(&block)
  result = internal_lock(&block)
  return false if result == NO_LOCK
  result
end

#lock!(exception_klass = PgLock::UnableToLockError) ⇒ Object

A PgLock::UnableToLock is raised if the lock is not acquired.


51
52
53
54
55
56
57
# File 'lib/pg_lock.rb', line 51

def lock!(exception_klass = PgLock::UnableToLockError)
  result = internal_lock { yield self if block_given? }
  if result == NO_LOCK
    raise exception_klass.new(name: name, attempts: max_attempts)
  end
  return result
end