Our great sponsors
-
InfluxDB
Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.
# https://github.com/rails/rails/blob/81c5c9971abe7a42a53ddbfede2683081a67e9d1/actionpack/lib/action_dispatch/middleware/request_id.rb require "securerandom" require "active_support/core_ext/string/access" module ActionDispatch # Makes a unique request id available to the +action_dispatch.request_id+ env variable (which is then accessible # through ActionDispatch::Request#request_id or the alias ActionDispatch::Request#uuid) and sends # the same id to the client via the X-Request-Id header. # # The unique request id is either based on the X-Request-Id header in the request, which would typically be generated # by a firewall, load balancer, or the web server, or, if this header is not available, a random uuid. If the # header is accepted from the outside world, we sanitize it to a max of 255 chars and alphanumeric and dashes only. # # The unique request id can be used to trace a request end-to-end and would typically end up being part of log files # from multiple pieces of the stack. class RequestId def initialize(app, header:) @app = app @header = header end def call(env) req = ActionDispatch::Request.new env req.request_id = make_request_id(req.headers[@header]) @app.call(env).tap { |_status, headers, _body| headers[@header] = req.request_id } end private def make_request_id(request_id) if request_id.presence request_id.gsub(/[^\w\-@]/, "").first(255) else internal_request_id end end def internal_request_id SecureRandom.uuid end end end
In rate_limited? the method request_counter is called which brings us to the part where Kredis is used. We use Kredis to initialize a counter in Redis. Kredis 'instantiates' the value from Redis. In other words, when you call Kredis.counter("mykey") we have an object that points to a Redis value under mykey. On that object we can call #increment which increments the current value in Redis. As you can see we check if the Redis key exists so that we can decide to use the call with expires_in. Each time you call #counter with expires_in, the expire timer resets. We don't want that because then the key will never expire. Checkout the Kredis docs for more information about Kredis.
And now you have created some middleware to implement a rate limiter with a test suite. You can find the source of the above Rails application here.