class Bottleneck::Core

Public Class Methods

new(ip) click to toggle source

Create a Core object.

@param [String] ip A name to uniquely identify this rate limit. For example, '127.0.0.1'

@return [Core] Core instance

# File lib/bottleneck/core.rb, line 10
def initialize(ip)
  @ip = ip.to_s
  @storage = Bottleneck.storage
  @limits = Bottleneck.config["limits"]
end

Public Instance Methods

run() click to toggle source

Run main logic initialization, set and read Redis keys and validation requests count and time limit.

@return [Hash] Hash with :status and :message keys

# File lib/bottleneck/core.rb, line 19
def run
  client_ip = @ip
  key = "request_count:#{client_ip}"
  result = { status: Constants::SUCCESS_STATUS, message: Constants::OK_MESSAGE }
  requests_count = @storage.get(key)
  unless requests_count
    @storage.set(key, 0)
    @storage.expire(key, @limits["time_period_seconds"])
  end
  if requests_count.to_i >= @limits["max_requests_count"]
    result[:status] = Constants::EXPIRED_STATUS
    result[:message] = message(period(key))
  else
    @storage.incr(key)
  end
  result
end

Private Instance Methods

message(secs) click to toggle source

Return string message for 429 status

@param [Integer] secs Remaining seconds

@return [String] Rate limit message with seconds

# File lib/bottleneck/core.rb, line 53
def message(secs)
  "Rate limit exceeded. Try again in #{secs} seconds"
end
period(key) click to toggle source

Get remaining time in seconds for key.

@param [String] key A unique key in Redis store

@return [Integer] Countdown in seconds

# File lib/bottleneck/core.rb, line 44
def period(key)
  @storage.ttl(key)
end