Module: Legion::Lock
- Defined in:
- lib/legion/lock.rb
Defined Under Namespace
Classes: NotAcquired
Constant Summary collapse
- RELEASE_SCRIPT =
<<~LUA if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end LUA
- EXTEND_SCRIPT =
<<~LUA if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("pexpire", KEYS[1], ARGV[2]) else return 0 end LUA
Class Method Summary collapse
- .acquire(name, ttl: 30_000) ⇒ Object
- .extend_lock(name, token, ttl: 30_000) ⇒ Object
- .locked?(name) ⇒ Boolean
- .release(name, token) ⇒ Object
- .with_lock(name, ttl: 30_000) ⇒ Object
Class Method Details
.acquire(name, ttl: 30_000) ⇒ Object
26 27 28 29 30 31 32 33 34 |
# File 'lib/legion/lock.rb', line 26 def acquire(name, ttl: 30_000) token = SecureRandom.uuid key = lock_key(name) result = with_redis { |conn| conn.set(key, token, nx: true, px: ttl) } result ? token : nil rescue StandardError => e Legion::Logging.debug "Lock#acquire failed for name=#{name}: #{e.}" if defined?(Legion::Logging) nil end |
.extend_lock(name, token, ttl: 30_000) ⇒ Object
54 55 56 57 58 59 60 61 |
# File 'lib/legion/lock.rb', line 54 def extend_lock(name, token, ttl: 30_000) key = lock_key(name) result = with_redis { |conn| conn.eval(EXTEND_SCRIPT, keys: [key], argv: [token, ttl.to_s]) } result == 1 rescue StandardError => e Legion::Logging.debug "Lock#extend_lock failed for name=#{name}: #{e.}" if defined?(Legion::Logging) false end |
.locked?(name) ⇒ Boolean
63 64 65 66 67 68 |
# File 'lib/legion/lock.rb', line 63 def locked?(name) with_redis { |conn| conn.exists?(lock_key(name)) } rescue StandardError => e Legion::Logging.debug "Lock#locked? failed for name=#{name}: #{e.}" if defined?(Legion::Logging) false end |
.release(name, token) ⇒ Object
36 37 38 39 40 41 42 43 |
# File 'lib/legion/lock.rb', line 36 def release(name, token) key = lock_key(name) result = with_redis { |conn| conn.eval(RELEASE_SCRIPT, keys: [key], argv: [token]) } result == 1 rescue StandardError => e Legion::Logging.debug "Lock#release failed for name=#{name}: #{e.}" if defined?(Legion::Logging) false end |
.with_lock(name, ttl: 30_000) ⇒ Object
45 46 47 48 49 50 51 52 |
# File 'lib/legion/lock.rb', line 45 def with_lock(name, ttl: 30_000) token = acquire(name, ttl: ttl) raise NotAcquired, "could not acquire lock: #{name}" unless token yield ensure release(name, token) if token end |