Class: Vox::HTTP::Middleware::RateLimiter

Inherits:
Faraday::Middleware
  • Object
show all
Defined in:
lib/vox/http/middleware/rate_limiter.rb

Overview

Faraday middleware to handle ratelimiting based on bucket ids and the rate limit key provided by Client#request in the request context

Instance Method Summary collapse

Constructor Details

#initialize(app, **_options) ⇒ RateLimiter

Returns a new instance of RateLimiter.



138
139
140
141
142
# File 'lib/vox/http/middleware/rate_limiter.rb', line 138

def initialize(app, **_options)
  super(app)
  @limit_table = LimitTable.new
  @mutex_table = Hash.new { |hash, key| hash[key] = Mutex.new }
end

Instance Method Details

#call(env) ⇒ Object

Request handler



145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/vox/http/middleware/rate_limiter.rb', line 145

def call(env)
  rl_key = env.request.context[:rl_key]
  req_id = env.request.context[:trace]
  mutex = @mutex_table[rl_key]

  mutex.synchronize do
    rl_wait(rl_key, req_id)
    rl_wait(:global, req_id)
    @app.call(env).on_complete do |environ|
      on_complete(environ, req_id)
    end
  end
end

#on_complete(env, req_id) ⇒ Object

Handler for response data



160
161
162
163
164
165
166
167
168
169
170
# File 'lib/vox/http/middleware/rate_limiter.rb', line 160

def on_complete(env, req_id)
  resp = env.response

  if resp.status == 429 && resp.headers['x-ratelimit-global']
    @limit_table.update_from_headers(:global, resp.headers, req_id)
    Thread.new { @limit_table.get_from_key(:global).lock_until_reset }
    LOGGER.error { "{#{req_id}}} Global ratelimit hit" }
  end

  update_from_headers(env)
end