class Locksy::Memory
Attributes
_data_change[W]
This is needed to allow tests to inject and control the condition variable
_datastore[R]
Public Class Methods
_notify_data_change()
click to toggle source
THIS IS DANGEROUS… CALL ONLY WHEN SYNCHRONIZED IN THE MUTEX
# File lib/locksy/memory.rb, line 68 def _notify_data_change @_data_change.broadcast end
_synchronize(&blk)
click to toggle source
# File lib/locksy/memory.rb, line 58 def _synchronize(&blk) @_singleton_mutex.synchronize(&blk) end
_wait_for_data_change(timeout = nil)
click to toggle source
THIS IS DANGEROUS… CALL ONLY WHEN SYNCHRONIZED IN THE MUTEX
# File lib/locksy/memory.rb, line 63 def _wait_for_data_change(timeout = nil) @_data_change.wait(@_singleton_mutex, timeout) end
release_all!()
click to toggle source
# File lib/locksy/memory.rb, line 54 def release_all! _synchronize { @_datastore = {} } end
Public Instance Methods
obtain_lock(expire_after: default_expiry, wait_for: nil, **_args)
click to toggle source
# File lib/locksy/memory.rb, line 9 def obtain_lock(expire_after: default_expiry, wait_for: nil, **_args) stop_waiting_at = wait_for ? now + wait_for : nil begin current = nil self.class._synchronize do current = _in_mutex_retrieve_lock self.class._datastore[lock_name] = [owner, expiry(expire_after)] self.class._notify_data_change end rescue LockNotOwnedError => ex if stop_waiting_at && stop_waiting_at > now # Maximum wait time for the condition variable before retrying # Because it is possible that a condition variable will not be # triggered, or may be triggered by something that is not what # was expected. # Retry at a maximum of 1/2 of the remaining time until the # current lock expires or the remaining time from the what the # caller was willing to wait, subject to a minimum of 0.1s to # prevent busy looping. cv_timeout = [stop_waiting_at - now, [(ex.current_expiry - now) / 2, 0.1].max].min self.class._synchronize { self.class._wait_for_data_change(cv_timeout) } retry unless self.class.shutting_down? end raise ex end end
refresh_lock(expire_after: default_extension, **_args)
click to toggle source
# File lib/locksy/memory.rb, line 44 def refresh_lock(expire_after: default_extension, **_args) obtain_lock expire_after: expire_after end
release_lock()
click to toggle source
# File lib/locksy/memory.rb, line 36 def release_lock self.class._synchronize do _in_mutex_retrieve_lock self.class._datastore.delete lock_name self.class._notify_data_change end end
Private Instance Methods
_in_mutex_retrieve_lock()
click to toggle source
# File lib/locksy/memory.rb, line 79 def _in_mutex_retrieve_lock current = self.class._datastore[lock_name] if current && current[0] != owner && current[1] > now raise LockNotOwnedError.new(lock: self, current_owner: current[0], current_expiry: current[1]) end current end