Sha256: a934ef26d5ceb8775d48bf9920af2780016e458996e7f0d9ba132d4ecc3dc10a
Contents?: true
Size: 1.41 KB
Versions: 2
Compression:
Stored size: 1.41 KB
Contents
require 'ratelimitcop/version' require 'redis' require 'redis-namespace' class Ratelimitcop attr_reader :name, :threshold, :interval, :time_span, :bucket_span def initialize(name:, threshold:, interval:, redis_connection: {}, time_span: 600, bucket_span: 5) @name = name @threshold = threshold @interval = interval @time_span = time_span @bucket_span = bucket_span raise ArgumentError if @interval > @time_span || @interval < @bucket_span @redis ||= Redis::Namespace.new(:limiter, redis: Redis.new(redis_connection)) @all_buckets_count = (@time_span / @bucket_span).floor @sliding_window_buckets_count = (@interval.to_f / @bucket_span).floor end def add(count: 1) key = [@name, bucket_index].join(':') @redis.multi do @redis.incrby(key, count) @redis.expire(key, @interval) end nil end def count current_bucket_index = bucket_index bucket_indices = @sliding_window_buckets_count.times.map do |i| (current_bucket_index - i) % @all_buckets_count end @redis.multi do bucket_indices.map do |i| key = [@name, i].join(':') @redis.get(key) end end.map(&:to_i).sum end def exec_within_threshold sleep @bucket_span while exceeded? yield end def exceeded? count >= @threshold end private def bucket_index ((Time.now.to_i % @all_buckets_count) / @bucket_span).floor end end
Version data entries
2 entries across 2 versions & 1 rubygems
Version | Path |
---|---|
ratelimitcop-1.0.1 | lib/ratelimitcop.rb |
ratelimitcop-1.0.0 | lib/ratelimitcop.rb |