class SimpleMutex::Mutex
Constants
- BaseError
- DEFAULT_EXPIRES_IN
- ERR_MSGS
- LockError
- UnlockError
Attributes
redis[RW]
expires_in[RW]
lock_key[RW]
payload[RW]
signature[RW]
Public Class Methods
lock(lock_key, **options)
click to toggle source
# File lib/simple_mutex/mutex.rb, line 44 def lock(lock_key, **options) new(lock_key, **options).lock end
lock!(lock_key, **options)
click to toggle source
# File lib/simple_mutex/mutex.rb, line 48 def lock!(lock_key, **options) new(lock_key, **options).lock! end
new(lock_key, expires_in: DEFAULT_EXPIRES_IN, signature: SecureRandom.uuid, payload: nil)
click to toggle source
# File lib/simple_mutex/mutex.rb, line 115 def initialize(lock_key, expires_in: DEFAULT_EXPIRES_IN, signature: SecureRandom.uuid, payload: nil) ::SimpleMutex.redis_check! self.lock_key = lock_key self.expires_in = expires_in.to_i self.signature = signature self.payload = payload end
raise_error(error_class, msg_template, lock_key)
click to toggle source
# File lib/simple_mutex/mutex.rb, line 97 def raise_error(error_class, msg_template, lock_key) template_base = error_class.name.split("::").last.gsub("Error", "").downcase.to_sym error_msg = ERR_MSGS[template_base][msg_template].call(lock_key) raise(error_class.new(error_msg, lock_key)) end
signature_valid?(raw_data, signature)
click to toggle source
# File lib/simple_mutex/mutex.rb, line 104 def signature_valid?(raw_data, signature) return false if raw_data.nil? JSON.parse(raw_data)["signature"] == signature rescue JSON::ParserError, TypeError false end
unlock(lock_key, signature: nil, force: false)
click to toggle source
# File lib/simple_mutex/mutex.rb, line 52 def unlock(lock_key, signature: nil, force: false) ::SimpleMutex.redis_check! redis = ::SimpleMutex.redis redis.watch(lock_key) do raw_data = redis.get(lock_key) if raw_data && (force || signature_valid?(raw_data, signature)) redis.multi { |multi| multi.del(lock_key) }.first.positive? else redis.unwatch false end end end
unlock!(lock_key, signature: nil, force: false)
click to toggle source
# File lib/simple_mutex/mutex.rb, line 69 def unlock!(lock_key, signature: nil, force: false) ::SimpleMutex.redis_check! redis = ::SimpleMutex.redis redis.watch(lock_key) do raw_data = redis.get(lock_key) begin raise_error(UnlockError, :key_not_found, lock_key) unless raw_data unless force || signature_valid?(raw_data, signature) raise_error(UnlockError, :signature_mismatch, lock_key) end success = redis.multi { |multi| multi.del(lock_key) }.first.positive? raise_error(UnlockError, :unknown, lock_key) unless success ensure redis.unwatch end end end
with_lock(lock_key, **options, &block)
click to toggle source
# File lib/simple_mutex/mutex.rb, line 93 def with_lock(lock_key, **options, &block) new(lock_key, **options).with_lock(&block) end
Public Instance Methods
lock()
click to toggle source
# File lib/simple_mutex/mutex.rb, line 127 def lock !!redis.set(lock_key, generate_data, nx: true, ex: expires_in) end
lock!()
click to toggle source
# File lib/simple_mutex/mutex.rb, line 149 def lock! lock or raise_error(LockError, :basic) end
lock_obtained?()
click to toggle source
# File lib/simple_mutex/mutex.rb, line 145 def lock_obtained? self.class.signature_valid?(redis.get(lock_key), signature) end
unlock(force: false)
click to toggle source
# File lib/simple_mutex/mutex.rb, line 131 def unlock(force: false) self.class.unlock(lock_key, signature: signature, force: force) end
unlock!(force: false)
click to toggle source
# File lib/simple_mutex/mutex.rb, line 153 def unlock!(force: false) self.class.unlock!(lock_key, signature: signature, force: force) end
with_lock() { || ... }
click to toggle source
# File lib/simple_mutex/mutex.rb, line 135 def with_lock lock! begin yield ensure unlock end end
Private Instance Methods
generate_data()
click to toggle source
# File lib/simple_mutex/mutex.rb, line 161 def generate_data JSON.generate( "signature" => signature, "created_at" => Time.now.to_s, "payload" => payload, ) end
raise_error(error_class, msg_template)
click to toggle source
# File lib/simple_mutex/mutex.rb, line 173 def raise_error(error_class, msg_template) self.class.raise_error(error_class, msg_template, lock_key) end
redis()
click to toggle source
# File lib/simple_mutex/mutex.rb, line 169 def redis ::SimpleMutex.redis end