Class: TranslationDiff::RateLimiters::Redis

Inherits:
Object
  • Object
show all
Defined in:
lib/translation_diff/rate_limiters/redis.rb

Constant Summary collapse

DEFAULT_THRESHOLD =
8000
DEFAULT_INTERVAL =
60
DEFAULT_NAMESPACE =
"translation-diff".freeze
SUBJECT =

This library limits the provider as a whole rather than per caller, so there is exactly one subject.

"call".freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection_pool, threshold: DEFAULT_THRESHOLD, interval: DEFAULT_INTERVAL, namespace: DEFAULT_NAMESPACE) ⇒ Redis

connection_pool is duck-typed to #with; neither connection_pool nor ratelimit is a hard dependency.



17
18
19
20
21
22
23
24
25
# File 'lib/translation_diff/rate_limiters/redis.rb', line 17

def initialize(connection_pool,
               threshold: DEFAULT_THRESHOLD,
               interval: DEFAULT_INTERVAL,
               namespace: DEFAULT_NAMESPACE)
  @connection_pool = connection_pool
  @threshold = threshold
  @interval = interval
  @namespace = namespace
end

Class Method Details

.build(config) ⇒ Object

An unset rate_limit must mean DEFAULT_THRESHOLD, not the nil that would override that keyword default.



10
11
12
13
14
# File 'lib/translation_diff/rate_limiters/redis.rb', line 10

def self.build(config)
  options = { interval: config.rate_interval, namespace: config.cache_namespace }
  options[:threshold] = config.rate_limit unless config.rate_limit.nil?
  new(config.redis_pool, **options)
end

Instance Method Details

#check(size) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/translation_diff/rate_limiters/redis.rb', line 27

def check(size)
  limiter_class = ratelimit_class

  connection_pool.with do |redis|
    rate_limit = limiter_class.new(namespace, redis: redis)
    exceeded = rate_limit.exceeded?(SUBJECT, threshold: threshold, interval: interval)
    raise TranslationDiff::RateLimitExceeded, exceeded_message if exceeded

    rate_limit.add(SUBJECT, size)
  end
end