FIX: Use the same time moment for related Redis calls in rate limiter (#11692)
Co-authored-by: Robin Ward robin.ward@gmail.com
diff --git a/lib/rate_limiter.rb b/lib/rate_limiter.rb
index 83761bf..78096d7 100644
--- a/lib/rate_limiter.rb
+++ b/lib/rate_limiter.rb
@@ -112,7 +112,7 @@ class RateLimiter
now = Time.now.to_i
if ((max || 0) <= 0) || rate_limiter_allowed?(now)
- raise RateLimiter::LimitExceeded.new(seconds_to_wait, @type) if raise_error
+ raise RateLimiter::LimitExceeded.new(seconds_to_wait(now), @type) if raise_error
false
else
true
@@ -173,20 +173,22 @@ class RateLimiter
Discourse.redis.without_namespace
end
- def seconds_to_wait
- @secs - age_of_oldest
+ def seconds_to_wait(now)
+ @secs - age_of_oldest(now)
end
- def age_of_oldest
+ def age_of_oldest(now)
# age of oldest event in buffer, in seconds
- Time.now.to_i - redis.lrange(prefixed_key, -1, -1).first.to_i
+ now - redis.lrange(prefixed_key, -1, -1).first.to_i
end
def is_under_limit?
+ now = Time.now.to_i
+
# number of events in buffer less than max allowed? OR
(redis.llen(prefixed_key) < @max) ||
- # age bigger or equal than sliding window size?
- (age_of_oldest >= @secs)
+ # age bigger than silding window size?
+ (age_of_oldest(now) >= @secs)
end
def rate_unlimited?
GitHub sha: 0f1c9a21