Class: CMDx::Limiters

Inherits:
Object
  • Object
show all
Defined in:
lib/cmdx/limiters.rb,
lib/cmdx/limiters/fixed_window.rb,
lib/cmdx/limiters/leaky_bucket.rb

Overview

Registry of named rate-limit strategies used by RateLimit. Ships with :fixed_window and :leaky_bucket. A limiter is any callable accepting a RateLimit::Quota and returning a RateLimit::Admission.

Defined Under Namespace

Modules: FixedWindow, LeakyBucket

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize ⇒ Limiters

Returns a new instance of Limiters.



11
12
13
14
15
16
# File 'lib/cmdx/limiters.rb', line 11

def initialize
  @registry = {
    fixed_window: Limiters::FixedWindow,
    leaky_bucket: Limiters::LeakyBucket
  }
end

Instance Attribute Details

#registry ⇒ Object (readonly)

Returns the value of attribute registry.



9
10
11
# File 'lib/cmdx/limiters.rb', line 9

def registry
  @registry
end

Instance Method Details

#deregister(name) ⇒ Limiters

Returns self for chaining.

Parameters:

  • name (Symbol)

Returns:



52
53
54
55
# File 'lib/cmdx/limiters.rb', line 52

def deregister(name)
  registry.delete(name)
  self
end

#empty? ⇒ Boolean

Returns:

  • (Boolean)


97
98
99
# File 'lib/cmdx/limiters.rb', line 97

def empty?
  registry.empty?
end

#initialize_copy(source) ⇒ void

This method returns an undefined value.

Parameters:

  • source (Limiters) —

    registry to duplicate



20
21
22
# File 'lib/cmdx/limiters.rb', line 20

def initialize_copy(source)
  @registry = source.registry.dup
end

#key?(name) ⇒ Boolean

Returns whether a limiter is registered under name.

Parameters:

  • name (Symbol)

Returns:

  • (Boolean) —

    whether a limiter is registered under name



59
60
61
# File 'lib/cmdx/limiters.rb', line 59

def key?(name)
  registry.key?(name)
end

#lookup(name) ⇒ #call

Returns the registered limiter.

Parameters:

  • name (Symbol)

Returns:

  • (#call) —

    the registered limiter

Raises:



66
67
68
69
70
71
72
73
# File 'lib/cmdx/limiters.rb', line 66

def lookup(name)
  registry[name] || begin
    raise UnknownEntryError, <<~MSG.chomp
      unknown limiter #{name.inspect}; registered: #{registry.keys.inspect}.
      See https://drexed.github.io/cmdx/rate_limit/#built-in-limiters
    MSG
  end
end

#register(name, callable = nil, &block) {|quota| ... } ⇒ Limiters

Registers a named limiter, overwriting any existing entry.

Parameters:

  • name (Symbol)
  • callable (#call, nil) (defaults to: nil) —

    pass either this or a block

  • block (#call, nil) —

    limiter callable when callable is omitted

Yield Parameters:

Yield Returns:

Returns:

Raises:

  • (ArgumentError) —

    when both callable and a block are given, or when the resolved limiter isn't callable



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/cmdx/limiters.rb', line 34

def register(name, callable = nil, &block)
  limiter = callable || block

  if callable && block
    raise ArgumentError, "limiter: provide either a callable or a block, not both"
  elsif !limiter.respond_to?(:call)
    raise ArgumentError, <<~MSG.chomp
      limiter must respond to #call (got #{limiter.class}).
      See https://drexed.github.io/cmdx/rate_limit/#custom-limiters-via-the-limiters-registry
    MSG
  end

  registry[name.to_sym] = limiter
  self
end

#resolve(spec) ⇒ #call?

Resolves a :limiter spec to a concrete callable.

Parameters:

  • spec (Symbol, #call, nil)

Returns:

  • (#call, nil)

Raises:



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/cmdx/limiters.rb', line 80

def resolve(spec)
  case spec
  when NilClass
    nil
  when Symbol
    lookup(spec)
  else
    return spec if spec.respond_to?(:call)

    raise UnknownEntryError, <<~MSG.chomp
      unknown limiter #{spec.inspect}; expected a Symbol from #{registry.keys.inspect} or a callable.
      See https://drexed.github.io/cmdx/rate_limit/#built-in-limiters
    MSG
  end
end

#size ⇒ Integer

Returns:

  • (Integer)


102
103
104
# File 'lib/cmdx/limiters.rb', line 102

def size
  registry.size
end