class RailsRateLimiter::Strategies::SlidingWindowLog
Constants
- TIMESTAMP_ACCURACY
Attributes
expires_in[R]
limit[R]
requester_pattern[R]
Public Class Methods
new(limit, per, requester, client = nil)
click to toggle source
@param limit [Fixnum, Lambda, Proc] The number of allowed
requests per time period.
@param per [Fixnum, Lambda, Proc] :per Time period in seconds. @param requester [Lambda, Proc] Identifies request @param client [Object, Proc] Redis client
# File lib/rails_rate_limiter/strategies/sliding_window_log.rb, line 16 def initialize(limit, per, requester, client = nil) @limit = limit.respond_to?(:call) ? limit.call : limit @expires_in = calculate_expires_in(per) @requester_pattern = requester @client = client.is_a?(Proc) ? client.call : client # Redis client already responds to #call so we have to strict end
Public Instance Methods
run()
click to toggle source
# File lib/rails_rate_limiter/strategies/sliding_window_log.rb, line 23 def run remove_expired_set_members return Result.new(time_left) if client.zcard(cache_key) >= limit log_request Result.new(0) end
Private Instance Methods
cache_key()
click to toggle source
# File lib/rails_rate_limiter/strategies/sliding_window_log.rb, line 53 def cache_key "rate_limiter_#{requester_pattern}" end
calculate_expires_in(per)
click to toggle source
# File lib/rails_rate_limiter/strategies/sliding_window_log.rb, line 61 def calculate_expires_in(per) value = per.respond_to?(:call) ? per.call : per (value.to_f * TIMESTAMP_ACCURACY).to_i end
client()
click to toggle source
# File lib/rails_rate_limiter/strategies/sliding_window_log.rb, line 32 def client @client ||= Redis.new end
current_timestamp()
click to toggle source
# File lib/rails_rate_limiter/strategies/sliding_window_log.rb, line 57 def current_timestamp @current_timestamp ||= (Time.zone.now.to_f * TIMESTAMP_ACCURACY).to_i end
log_request()
click to toggle source
Adds requests to SORTED SET with expiring_timestamp and current_timestamp
# File lib/rails_rate_limiter/strategies/sliding_window_log.rb, line 43 def log_request expiring_timestamp = current_timestamp + expires_in client.zadd(cache_key, expiring_timestamp, current_timestamp) end
remove_expired_set_members()
click to toggle source
Removes all SORTED SET members that have a score < current_timestamp
# File lib/rails_rate_limiter/strategies/sliding_window_log.rb, line 37 def remove_expired_set_members client.zremrangebyscore(cache_key, '-inf', "(#{current_timestamp}") end
time_left()
click to toggle source
# File lib/rails_rate_limiter/strategies/sliding_window_log.rb, line 48 def time_left timestamp = client.zrange(cache_key, 0, 0, with_scores: true)[0][1] ((timestamp - current_timestamp).to_f / TIMESTAMP_ACCURACY).ceil end