Class: Discordrb::Commands::Bucket
- Inherits:
-
Object
- Object
- Discordrb::Commands::Bucket
- Defined in:
- lib/discordrb/commands/rate_limiter.rb
Overview
This class represents a bucket for rate limiting - it keeps track of how many requests have been made and when exactly the user should be rate limited.
Instance Method Summary collapse
-
#clean(rate_limit_time = nil) ⇒ Object
Cleans the bucket, removing all elements that aren't necessary anymore.
-
#initialize(limit, time_span, delay) ⇒ Bucket
constructor
Makes a new bucket.
-
#rate_limited?(thing, rate_limit_time = nil, increment: 1) ⇒ Integer, false
Performs a rate limiting request.
Constructor Details
#initialize(limit, time_span, delay) ⇒ Bucket
Makes a new bucket
11 12 13 14 15 16 17 18 19 |
# File 'lib/discordrb/commands/rate_limiter.rb', line 11 def initialize(limit, time_span, delay) raise ArgumentError, '`limit` and `time_span` have to either both be set or both be nil!' if !limit != !time_span @limit = limit @time_span = time_span @delay = delay @bucket = {} end |
Instance Method Details
#clean(rate_limit_time = nil) ⇒ Object
Cleans the bucket, removing all elements that aren't necessary anymore
23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/discordrb/commands/rate_limiter.rb', line 23 def clean(rate_limit_time = nil) rate_limit_time ||= Time.now @bucket.delete_if do |_, limit_hash| # Time limit has not run out return false if @time_span && rate_limit_time < (limit_hash[:set_time] + @time_span) # Delay has not run out return false if @delay && rate_limit_time < (limit_hash[:last_time] + @delay) true end end |
#rate_limited?(thing, rate_limit_time = nil, increment: 1) ⇒ Integer, false
Performs a rate limiting request
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/discordrb/commands/rate_limiter.rb', line 42 def rate_limited?(thing, rate_limit_time = nil, increment: 1) key = resolve_key thing limit_hash = @bucket[key] # First case: limit_hash doesn't exist yet unless limit_hash @bucket[key] = { last_time: Time.now, set_time: Time.now, count: increment } return false end # Define the time at which we're being rate limited once so it doesn't get inaccurate rate_limit_time ||= Time.now if @limit && (limit_hash[:count] + increment) > @limit # Second case: Count is over the limit and the time has not run out yet return (limit_hash[:set_time] + @time_span) - rate_limit_time if @time_span && rate_limit_time < (limit_hash[:set_time] + @time_span) # Third case: Count is over the limit but the time has run out # Don't return anything here because there may still be delay-based limiting limit_hash[:set_time] = rate_limit_time limit_hash[:count] = 0 end if @delay && rate_limit_time < (limit_hash[:last_time] + @delay) # Fourth case: we're being delayed (limit_hash[:last_time] + @delay) - rate_limit_time else # Fifth case: no rate limiting at all! Increment the count, set the last_time, and return false limit_hash[:last_time] = rate_limit_time limit_hash[:count] += increment false end end |