Class: Locksy::Memory
- Inherits:
-
BaseLock
- Object
- LockInterface
- BaseLock
- Locksy::Memory
- Defined in:
- lib/locksy/memory.rb
Class Attribute Summary collapse
-
._data_change ⇒ Object
writeonly
This is needed to allow tests to inject and control the condition variable.
-
._datastore ⇒ Object
readonly
Returns the value of attribute _datastore.
Attributes inherited from BaseLock
#_clock, #default_expiry, #default_extension, #lock_name, #owner
Attributes inherited from LockInterface
#default_expiry, #default_extension, #lock_name, #owner
Class Method Summary collapse
-
._notify_data_change ⇒ Object
THIS IS DANGEROUS…
- ._synchronize(&blk) ⇒ Object
-
._wait_for_data_change(timeout = nil) ⇒ Object
THIS IS DANGEROUS…
- .release_all! ⇒ Object
Instance Method Summary collapse
- #obtain_lock(expire_after: default_expiry, wait_for: nil, **_args) ⇒ Object
- #refresh_lock(expire_after: default_extension, **_args) ⇒ Object
- #release_lock ⇒ Object
Methods inherited from BaseLock
#initialize, shutting_down?, #with_lock
Methods inherited from LockInterface
Constructor Details
This class inherits a constructor from Locksy::BaseLock
Class Attribute Details
._data_change=(value) ⇒ Object (writeonly)
This is needed to allow tests to inject and control the condition variable
52 53 54 |
# File 'lib/locksy/memory.rb', line 52 def _data_change=(value) @_data_change = value end |
._datastore ⇒ Object (readonly)
Returns the value of attribute _datastore.
49 50 51 |
# File 'lib/locksy/memory.rb', line 49 def _datastore @_datastore end |
Class Method Details
._notify_data_change ⇒ Object
THIS IS DANGEROUS… CALL ONLY WHEN SYNCHRONIZED IN THE MUTEX
68 69 70 |
# File 'lib/locksy/memory.rb', line 68 def _notify_data_change @_data_change.broadcast end |
._synchronize(&blk) ⇒ Object
58 59 60 |
# File 'lib/locksy/memory.rb', line 58 def _synchronize(&blk) @_singleton_mutex.synchronize(&blk) end |
._wait_for_data_change(timeout = nil) ⇒ Object
THIS IS DANGEROUS… CALL ONLY WHEN SYNCHRONIZED IN THE MUTEX
63 64 65 |
# File 'lib/locksy/memory.rb', line 63 def _wait_for_data_change(timeout = nil) @_data_change.wait(@_singleton_mutex, timeout) end |
.release_all! ⇒ Object
54 55 56 |
# File 'lib/locksy/memory.rb', line 54 def release_all! _synchronize { @_datastore = {} } end |
Instance Method Details
#obtain_lock(expire_after: default_expiry, wait_for: nil, **_args) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# 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) ⇒ Object
44 45 46 |
# File 'lib/locksy/memory.rb', line 44 def refresh_lock(expire_after: default_extension, **_args) obtain_lock expire_after: expire_after end |
#release_lock ⇒ Object
36 37 38 39 40 41 42 |
# 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 |