Class: Postburner::AdvisoryLock
- Inherits:
-
Object
- Object
- Postburner::AdvisoryLock
- Defined in:
- lib/postburner/advisory_lock.rb
Overview
PostgreSQL advisory lock support for coordinating distributed processes.
Advisory locks allow multiple scheduler processes to coordinate without race conditions. Only one process can hold a specific lock at a time.
Constant Summary collapse
- SCHEDULER_LOCK_KEY =
Lock key for the scheduler process
'postburner_scheduler'
Instance Attribute Summary collapse
-
#connection ⇒ Object
readonly
Returns the value of attribute connection.
-
#key ⇒ Object
readonly
Returns the value of attribute key.
Class Method Summary collapse
-
.with_lock(key, blocking: true) { ... } ⇒ Object?
Execute a block with an advisory lock.
Instance Method Summary collapse
-
#acquire ⇒ Boolean
Acquire the advisory lock (blocking).
-
#acquired? ⇒ Boolean
Check if this lock instance has acquired the lock.
-
#initialize(key, connection = nil) ⇒ AdvisoryLock
constructor
Initialize a new advisory lock.
-
#release ⇒ Boolean
Release the advisory lock.
-
#try_acquire ⇒ Boolean
Try to acquire the advisory lock (non-blocking).
Constructor Details
#initialize(key, connection = nil) ⇒ AdvisoryLock
Initialize a new advisory lock
35 36 37 38 39 |
# File 'lib/postburner/advisory_lock.rb', line 35 def initialize(key, connection = nil) @key = key @connection = connection || ActiveRecord::Base.connection @acquired = false end |
Instance Attribute Details
#connection ⇒ Object (readonly)
Returns the value of attribute connection.
29 30 31 |
# File 'lib/postburner/advisory_lock.rb', line 29 def connection @connection end |
#key ⇒ Object (readonly)
Returns the value of attribute key.
29 30 31 |
# File 'lib/postburner/advisory_lock.rb', line 29 def key @key end |
Class Method Details
.with_lock(key, blocking: true) { ... } ⇒ Object?
Execute a block with an advisory lock
94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/postburner/advisory_lock.rb', line 94 def self.with_lock(key, blocking: true) lock = new(key) acquired = blocking ? lock.acquire : lock.try_acquire return nil unless acquired begin yield ensure lock.release end end |
Instance Method Details
#acquire ⇒ Boolean
Acquire the advisory lock (blocking)
This will wait until the lock is available.
46 47 48 49 50 51 52 |
# File 'lib/postburner/advisory_lock.rb', line 46 def acquire return true if @acquired lock_id = generate_lock_id(key) result = connection.execute("SELECT pg_advisory_lock(#{lock_id})") @acquired = true end |
#acquired? ⇒ Boolean
Check if this lock instance has acquired the lock
84 85 86 |
# File 'lib/postburner/advisory_lock.rb', line 84 def acquired? @acquired end |
#release ⇒ Boolean
Release the advisory lock
71 72 73 74 75 76 77 78 79 |
# File 'lib/postburner/advisory_lock.rb', line 71 def release return false unless @acquired lock_id = generate_lock_id(key) result = connection.execute("SELECT pg_advisory_unlock(#{lock_id})").first @acquired = false value = result['pg_advisory_unlock'] value == true || value == 't' end |
#try_acquire ⇒ Boolean
Try to acquire the advisory lock (non-blocking)
Returns immediately, indicating whether lock was acquired.
59 60 61 62 63 64 65 66 |
# File 'lib/postburner/advisory_lock.rb', line 59 def try_acquire return true if @acquired lock_id = generate_lock_id(key) result = connection.execute("SELECT pg_try_advisory_lock(#{lock_id})").first value = result['pg_try_advisory_lock'] @acquired = value == true || value == 't' end |