Class: PgLock
- Inherits:
-
Object
- Object
- PgLock
- 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
- VERSION =
"0.1.2"
Instance Method Summary collapse
- #aquired? ⇒ Boolean (also: #has_lock?)
- #create ⇒ Object
- #delete ⇒ Object
-
#initialize(name:, attempts: 3, attempt_interval: 1, ttl: 60, connection: DEFAULT_CONNECTION_CONNECTOR.call, log: DEFAULT_LOGGER.call) ⇒ PgLock
constructor
A new instance of PgLock.
-
#lock(&block) ⇒ Object
Runs the given block if an advisory lock is able to be acquired.
-
#lock!(exception_klass = PgLock::UnableToLockError) ⇒ Object
A PgLock::UnableToLock is raised if the lock is not acquired.
Constructor Details
#initialize(name:, attempts: 3, attempt_interval: 1, ttl: 60, connection: DEFAULT_CONNECTION_CONNECTOR.call, log: DEFAULT_LOGGER.call) ⇒ PgLock
Returns a new instance of PgLock.
30 31 32 33 34 35 36 37 38 39 |
# File 'lib/pg_lock.rb', line 30 def initialize(name:, attempts: 3, attempt_interval: 1, ttl: 60, connection: DEFAULT_CONNECTION_CONNECTOR.call, log: DEFAULT_LOGGER.call ) 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 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?
87 88 89 |
# File 'lib/pg_lock.rb', line 87 def aquired? locket.active? end |
#create ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/pg_lock.rb', line 64 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 |
#delete ⇒ Object
76 77 78 79 80 81 82 83 84 85 |
# File 'lib/pg_lock.rb', line 76 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.
42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/pg_lock.rb', line 42 def lock(&block) if create begin Timeout::timeout(ttl, &block) if block_given? ensure delete end return true else return false end end |
#lock!(exception_klass = PgLock::UnableToLockError) ⇒ Object
A PgLock::UnableToLock is raised if the lock is not acquired.
56 57 58 59 60 61 62 |
# File 'lib/pg_lock.rb', line 56 def lock!(exception_klass = PgLock::UnableToLockError) if lock { yield self if block_given? } # lock successful, do nothing else raise exception_klass.new(name: name, attempts: max_attempts) end end |