Class: TrafficJam::RollingLimit
- Defined in:
- lib/traffic_jam/rolling_limit.rb
Overview
This class represents a rolling limit on an action, value pair. For example, if limiting the amount of money a user can transfer in a week, the action could be :transfers
and the value would be the user ID. The class exposes atomic increment operations and allows querying of the current amount used and amount remaining.
This class also handles 0 for period, where 0 is no period (each request is compared to the max).
This class departs from the design of Limit by tracking a sum of the actions in a second, in a hash keyed by the timestamp. Therefore, this limit can put a lot of data size pressure on the Redis storage, so use it wisely.
Instance Attribute Summary
Attributes inherited from Limit
#action, #max, #period, #value
Instance Method Summary collapse
-
#increment(amount = 1, time: Time.now) ⇒ Boolean
Increment the amount used by the given number.
-
#initialize(action, value, max: nil, period: nil) ⇒ RollingLimit
constructor
Constructor takes an action name as a symbol, a maximum cap, and the period of limit.
-
#used ⇒ Integer
Return amount of limit used.
Methods inherited from Limit
#decrement, #exceeded?, #flatten, #increment!, #limit_exceeded, #remaining, #reset
Constructor Details
#initialize(action, value, max: nil, period: nil) ⇒ RollingLimit
Constructor takes an action name as a symbol, a maximum cap, and the period of limit. max
and period
are required keyword arguments.
25 26 27 |
# File 'lib/traffic_jam/rolling_limit.rb', line 25 def initialize(action, value, max: nil, period: nil) super(action, value, max: max, period: period) end |
Instance Method Details
#increment(amount = 1, time: Time.now) ⇒ Boolean
Increment the amount used by the given number. Rolls back the increment if the operation exceeds the limit. Returns whether the operation was successful. Time of increment can be specified optionally with a keyword argument, which is not really useful since it be undone by used.
38 39 40 41 42 43 44 45 46 |
# File 'lib/traffic_jam/rolling_limit.rb', line 38 def increment(amount = 1, time: Time.now) raise ArgumentError, 'Amount must be an integer' if amount != amount.to_i return amount <= 0 if max.zero? return amount <= max if period.zero? return true if amount.zero? return false if amount > max !run_incr([time.to_i, amount.to_i, max, period]).nil? end |
#used ⇒ Integer
Return amount of limit used
51 52 53 54 |
# File 'lib/traffic_jam/rolling_limit.rb', line 51 def used return 0 if max.zero? || period.zero? [sum, max].min end |