Class: Stoplight::Infrastructure::Redis::DataStore::RecoveryLockStore
- Inherits:
-
Object
- Object
- Stoplight::Infrastructure::Redis::DataStore::RecoveryLockStore
- Defined in:
- lib/stoplight/infrastructure/redis/data_store/recovery_lock_store.rb,
sig/_private/stoplight/infrastructure/redis/data_store/recovery_lock_store.rbs
Overview
Distributed recovery lock using Redis SET NX (set-if-not-exists).
Lock Acquisition:
- Uses unique UUID token to prevent accidental release of others' locks
- Atomic SET with NX flag ensures only one process acquires recovery_lock
- TTL (px: lock_timeout) auto-releases recovery_lock if process crashes
Lock Release:
- Lua script ensures only token holder can release (token comparison)
- Best-effort release; TTL cleanup handles failures
Failure Modes:
- Lock contention: Returns false, caller should skip probe
- Redis unavailable: raises an error and let caller decide
- Crashed holder: raises an error and let caller decide. Lock auto-expires after lock_timeout
- Release failure: Lock auto-expires after lock_timeout
Instance Attribute Summary collapse
-
#lock_timeout ⇒ Integer
readonly
Returns the value of attribute lock_timeout.
-
#redis ⇒ redis
readonly
Returns the value of attribute redis.
-
#scripting ⇒ Scripting
readonly
Returns the value of attribute scripting.
Instance Method Summary collapse
- #acquire_lock(light_name) ⇒ RecoveryLockToken?
-
#initialize(redis:, lock_timeout:, scripting:) ⇒ RecoveryLockStore
constructor
A new instance of RecoveryLockStore.
- #release_lock(recovery_lock) ⇒ void
Constructor Details
#initialize(redis:, lock_timeout:, scripting:) ⇒ RecoveryLockStore
Returns a new instance of RecoveryLockStore.
28 29 30 31 32 |
# File 'lib/stoplight/infrastructure/redis/data_store/recovery_lock_store.rb', line 28 def initialize(redis:, lock_timeout:, scripting:) @redis = redis @lock_timeout = lock_timeout @scripting = scripting end |
Instance Attribute Details
#lock_timeout ⇒ Integer (readonly)
Returns the value of attribute lock_timeout.
54 55 56 |
# File 'lib/stoplight/infrastructure/redis/data_store/recovery_lock_store.rb', line 54 def lock_timeout @lock_timeout end |
#redis ⇒ redis (readonly)
Returns the value of attribute redis.
53 54 55 |
# File 'lib/stoplight/infrastructure/redis/data_store/recovery_lock_store.rb', line 53 def redis @redis end |
#scripting ⇒ Scripting (readonly)
Returns the value of attribute scripting.
55 56 57 |
# File 'lib/stoplight/infrastructure/redis/data_store/recovery_lock_store.rb', line 55 def scripting @scripting end |
Instance Method Details
#acquire_lock(light_name) ⇒ RecoveryLockToken?
34 35 36 37 38 39 40 41 42 |
# File 'lib/stoplight/infrastructure/redis/data_store/recovery_lock_store.rb', line 34 def acquire_lock(light_name) recovery_lock = RecoveryLockToken.new(light_name:) acquired = !!redis.then do |client| client.set(recovery_lock.lock_key, recovery_lock.token, nx: true, px: lock_timeout) end recovery_lock if acquired end |
#release_lock(recovery_lock) ⇒ void
This method returns an undefined value.
44 45 46 47 48 49 |
# File 'lib/stoplight/infrastructure/redis/data_store/recovery_lock_store.rb', line 44 def release_lock(recovery_lock) scripting.call( :release_lock, keys: [recovery_lock.lock_key], args: [recovery_lock.token] ) end |