Module: Farce::Abstract::Counter Abstract
- Includes:
- Value, Internal::Copyable, Internal::ValueSerialization, Internal::Inspect, Internal::MarshalSupport::Counter
- Included in:
- Counter, Local::Counter
- Defined in:
- lib/farce/abstract/counter.rb,
lib/farce/integrations/psych.rb
Overview
Common numeric interface and atomic operations for counters.
This is a module rather than a class so Counter can inherit directly from the native counter and avoid delegation overhead.
Class Method Summary collapse
Instance Method Summary collapse
- #add(by = 1) ⇒ BasicObject
-
#decrement_if_above(floor) ⇒ Boolean
Decrement the counter by one if its current value is above the floor.
-
#increment_if_below(limit) ⇒ Boolean
Increment the counter by one if its current value is below the limit.
-
#reset ⇒ self
Reset the counter to its initial value.
-
#wait_until(timeout: nil) {|value| ... } ⇒ Integer?
Wait until a block condition matches the current value.
-
#wait_until_above(floor, timeout: nil) ⇒ Integer?
Wait until the value is strictly above the floor.
-
#wait_until_below(limit, timeout: nil) ⇒ Integer?
Wait until the value is strictly below the limit.
-
#wait_until_changed(expected, timeout: nil) { ... } ⇒ Integer, ...
Wait until the current value differs from the expected value.
-
#wait_until_match(object, timeout: nil) ⇒ Integer?
Wait until
object === valueis true. -
#wait_until_value(object, timeout: nil) ⇒ Integer?
Wait until
object == valueis true. -
#wait_while(timeout: nil) {|value| ... } ⇒ Integer?
Wait while the block returns a truthy value.
-
#wait_while_above(limit, timeout: nil) ⇒ Integer?
Wait while the value is strictly above the limit.
-
#wait_while_below(floor, timeout: nil) ⇒ Integer?
Wait while the value is strictly below the floor.
-
#wait_while_match(object, timeout: nil) ⇒ Integer?
Wait while
object === valueis true. -
#wait_while_value { ... } ⇒ Integer, ...
Wait until the current value differs from the expected value.
Methods included from Internal::ValueSerialization
#as_extended_json, #as_json, #to_bson, #to_bson_normalized_value, #to_cbor, #to_json, #to_msgpack
Methods included from Value
Methods included from Internal::Copyable
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing ⇒ BasicObject (private)
189 |
# File 'lib/farce/abstract/counter.rb', line 189 def method_missing(...) = value.public_send(...) |
Class Method Details
.included(base) ⇒ BasicObject
15 16 17 18 |
# File 'lib/farce/abstract/counter.rb', line 15 def self.included(base) Internal.prepare_mutable_numeric(base) super end |
Instance Method Details
#add(by = 1) ⇒ BasicObject
172 |
# File 'lib/farce/abstract/counter.rb', line 172 def add(...) = increment(...) |
#decrement_if_above(floor) ⇒ Boolean
Decrement the counter by one if its current value is above the floor. The check and decrement happen atomically.
156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/farce/abstract/counter.rb', line 156 def decrement_if_above(floor) # rubocop:disable Naming/PredicateMethod floor = Integer(floor) current = value Internal::Freeze.check(self) while current > floor return true if compare_and_set(current, current - 1) current = value end false end |
#increment_if_below(limit) ⇒ Boolean
Increment the counter by one if its current value is below the limit. The check and increment happen atomically.
138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/farce/abstract/counter.rb', line 138 def increment_if_below(limit) # rubocop:disable Naming/PredicateMethod limit = Integer(limit) current = value Internal::Freeze.check(self) while current < limit return true if compare_and_set(current, current + 1) current = value end false end |
#reset ⇒ self
Reset the counter to its initial value.
129 130 131 132 |
# File 'lib/farce/abstract/counter.rb', line 129 def reset self.value = initial self end |
#wait_until(timeout: nil) {|value| ... } ⇒ Integer?
Wait until a block condition matches the current value. One timeout budget covers all checks and waits. The block is not interrupted.
50 |
# File 'lib/farce/abstract/counter.rb', line 50 def wait_until(timeout: nil, &) = Internal.wait_until(self, timeout:, &) |
#wait_until_above(floor, timeout: nil) ⇒ Integer?
Wait until the value is strictly above the floor.
104 105 106 107 |
# File 'lib/farce/abstract/counter.rb', line 104 def wait_until_above(floor, timeout: nil) floor = Integer(floor) wait_until(timeout:) { |value| value > floor } end |
#wait_until_below(limit, timeout: nil) ⇒ Integer?
Wait until the value is strictly below the limit.
95 96 97 98 |
# File 'lib/farce/abstract/counter.rb', line 95 def wait_until_below(limit, timeout: nil) limit = Integer(limit) wait_until(timeout:) { |value| value < limit } end |
#wait_until_changed(expected, timeout: nil) { ... } ⇒ Integer, ...
Wait until the current value differs from the expected value.
32 33 34 35 36 37 38 39 40 41 |
# File 'lib/farce/abstract/counter.rb', line 32 def wait_until_changed(expected, timeout: nil) signal = change_signal Internal.with_timeout(timeout) do |_, deadline| observed = signal.generation current = value return current unless expected == current break unless signal.wait(observed, timeout: Internal.remaining_timeout(deadline)) end yield if block_given? end |
#wait_until_match(object, timeout: nil) ⇒ Integer?
Wait until object === value is true.
87 88 89 |
# File 'lib/farce/abstract/counter.rb', line 87 def wait_until_match(object, timeout: nil) wait_until(timeout:) { |value| object === value } # rubocop:disable Style/CaseEquality end |
#wait_until_value(object, timeout: nil) ⇒ Integer?
Wait until object == value is true.
Counters compare integer values by equality.
79 80 81 |
# File 'lib/farce/abstract/counter.rb', line 79 def wait_until_value(object, timeout: nil) wait_until(timeout:) { |value| object == value } end |
#wait_while(timeout: nil) {|value| ... } ⇒ Integer?
Wait while the block returns a truthy value.
58 59 60 61 |
# File 'lib/farce/abstract/counter.rb', line 58 def wait_while(timeout: nil) raise LocalJumpError, "no block given" unless block_given? wait_until(timeout:) { |value| !yield(value) } end |
#wait_while_above(limit, timeout: nil) ⇒ Integer?
Wait while the value is strictly above the limit.
113 114 115 116 |
# File 'lib/farce/abstract/counter.rb', line 113 def wait_while_above(limit, timeout: nil) limit = Integer(limit) wait_until(timeout:) { |value| value <= limit } end |
#wait_while_below(floor, timeout: nil) ⇒ Integer?
Wait while the value is strictly below the floor.
122 123 124 125 |
# File 'lib/farce/abstract/counter.rb', line 122 def wait_while_below(floor, timeout: nil) floor = Integer(floor) wait_until(timeout:) { |value| value >= floor } end |
#wait_while_match(object, timeout: nil) ⇒ Integer?
Wait while object === value is true.
67 68 69 |
# File 'lib/farce/abstract/counter.rb', line 67 def wait_while_match(object, timeout: nil) wait_while(timeout:) { |value| object === value } # rubocop:disable Style/CaseEquality end |
#wait_while_value { ... } ⇒ Integer, ...
Wait until the current value differs from the expected value.
72 |
# File 'lib/farce/abstract/counter.rb', line 72 def wait_while_value(...) = wait_until_changed(...) |