Class: TrafficJam::LimitGroup
- Inherits:
-
Object
- Object
- TrafficJam::LimitGroup
- Defined in:
- lib/traffic_jam/limit_group.rb
Overview
A limit group is a way of enforcing a cap over a set of limits with the guarantee that either all limits will be incremented or none. This is useful if you must check multiple limits before allowing an action to be taken. Limit groups can contain other limit groups.
Instance Attribute Summary collapse
-
#limits ⇒ Object
readonly
Returns the value of attribute limits.
Instance Method Summary collapse
-
#<<(limit) ⇒ Object
Add a limit to the group.
-
#decrement(amount = 1, time: Time.now) ⇒ true
Decrement the limits by the given amount.
-
#exceeded?(amount = 1) ⇒ Boolean
Return whether incrementing by the given amount would exceed any limit.
-
#flatten ⇒ Array<TrafficJam::Limit>
Return flattened list of limit.
-
#increment(amount = 1, time: Time.now) ⇒ Boolean
Attempt to increment the limits by the given amount.
-
#increment!(amount = 1, time: Time.now) ⇒ nil
Increment the limits by the given amount.
-
#initialize(*limits, ignore_nil_values: false) ⇒ LimitGroup
constructor
Creates a limit group from a collection of limits or other limit groups.
-
#limit_exceeded(amount = 1) ⇒ TrafficJam::Limit?
Return the first limit to be exceeded if incrementing by the given amount, or nil otherwise.
-
#remaining ⇒ Integer
Return minimum amount remaining of any limit.
-
#reset ⇒ Object
Resets all limits to 0.
Constructor Details
#initialize(*limits, ignore_nil_values: false) ⇒ LimitGroup
Creates a limit group from a collection of limits or other limit groups.
14 15 16 17 18 19 20 21 22 |
# File 'lib/traffic_jam/limit_group.rb', line 14 def initialize(*limits, ignore_nil_values: false) @limits = limits.flatten @ignore_nil_values = ignore_nil_values if @ignore_nil_values @limits.reject! do |limit| limit.respond_to?(:value) && limit.value.nil? end end end |
Instance Attribute Details
#limits ⇒ Object (readonly)
Returns the value of attribute limits.
7 8 9 |
# File 'lib/traffic_jam/limit_group.rb', line 7 def limits @limits end |
Instance Method Details
#<<(limit) ⇒ Object
Add a limit to the group.
27 28 29 30 31 |
# File 'lib/traffic_jam/limit_group.rb', line 27 def <<(limit) if !(@ignore_nil_values && limit.value.nil?) limits << limit end end |
#decrement(amount = 1, time: Time.now) ⇒ true
Decrement the limits by the given amount.
82 83 84 |
# File 'lib/traffic_jam/limit_group.rb', line 82 def decrement(amount = 1, time: Time.now) limits.all? { |limit| limit.decrement(amount, time: time) } end |
#exceeded?(amount = 1) ⇒ Boolean
Return whether incrementing by the given amount would exceed any limit. Does not change amount used.
91 92 93 |
# File 'lib/traffic_jam/limit_group.rb', line 91 def exceeded?(amount = 1) limits.any? { |limit| limit.exceeded?(amount) } end |
#flatten ⇒ Array<TrafficJam::Limit>
Return flattened list of limit. Will return list limits even if this group contains nested limit groups.
125 126 127 |
# File 'lib/traffic_jam/limit_group.rb', line 125 def flatten limits.map(&:flatten).flatten end |
#increment(amount = 1, time: Time.now) ⇒ Boolean
Attempt to increment the limits by the given amount. Does not increment if incrementing would exceed any limit.
39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/traffic_jam/limit_group.rb', line 39 def increment(amount = 1, time: Time.now) exceeded_index = limits.find_index do |limit| !limit.increment(amount, time: time) end if exceeded_index limits[0...exceeded_index].each do |limit| limit.decrement(amount, time: time) end end exceeded_index.nil? end |
#increment!(amount = 1, time: Time.now) ⇒ nil
Increment the limits by the given amount. Raises an error and does not increment if doing so would exceed any limit.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/traffic_jam/limit_group.rb', line 59 def increment!(amount = 1, time: Time.now) exception = nil exceeded_index = limits.find_index do |limit| begin limit.increment!(amount, time: time) rescue TrafficJam::LimitExceededError => e exception = e true end end if exceeded_index limits[0...exceeded_index].each do |limit| limit.decrement(amount, time: time) end raise exception end end |
#limit_exceeded(amount = 1) ⇒ TrafficJam::Limit?
Return the first limit to be exceeded if incrementing by the given amount, or nil otherwise. Does not change amount used for any limit.
100 101 102 103 104 105 106 |
# File 'lib/traffic_jam/limit_group.rb', line 100 def limit_exceeded(amount = 1) limits.each do |limit| limit_exceeded = limit.limit_exceeded(amount) return limit_exceeded if limit_exceeded end nil end |
#remaining ⇒ Integer
Return minimum amount remaining of any limit.
117 118 119 |
# File 'lib/traffic_jam/limit_group.rb', line 117 def remaining limits.map(&:remaining).min end |
#reset ⇒ Object
Resets all limits to 0.
109 110 111 112 |
# File 'lib/traffic_jam/limit_group.rb', line 109 def reset limits.each(&:reset) nil end |