Sha256: 57408c39e6705b29860b4ef75a7f61ddf64324f30247e740094307bed669b22b

Contents?: true

Size: 1.84 KB

Versions: 4

Compression:

Stored size: 1.84 KB

Contents

# frozen_string_literal: true

module Discorb
  #
  # Class to handle rate limiting.
  # @private
  #
  class RatelimitHandler
    # @private
    def initialize(client)
      @client = client
      @current_ratelimits = {}
      @path_ratelimit_bucket = {}
      @global = false
    end

    def inspect
      "#<#{self.class}>"
    end

    #
    # Wait for the rate limit to reset.
    #
    # @param [String] method The HTTP method.
    # @param [String] path The path.
    #
    def wait(method, path)
      return if path.start_with?("https://")

      if @global && @global > Time.now.to_f
        time = @global - Time.now.to_f
        @client.log.info("global rate limit reached, waiting #{time} seconds")
        sleep(time)
        @global = false
      end

      return unless hash = @path_ratelimit_bucket[method + path]

      return unless b = @current_ratelimits[hash]

      if b[:reset_at] < Time.now.to_f
        @current_ratelimits.delete(hash)
        return
      end
      return if b[:remaining] > 0

      time = b[:reset_at] - Time.now.to_f
      @client.log.info("rate limit for #{method} #{path} reached, waiting #{time} seconds")
      sleep(time)
    end

    #
    # Save the rate limit.
    #
    # @param [String] method The HTTP method.
    # @param [String] path The path.
    # @param [Net::HTTPResponse] resp The response.
    #
    def save(method, path, resp)
      if resp["X-Ratelimit-Global"] == "true"
        @global = Time.now.to_f + JSON.parse(resp.body, symbolize_names: true)[:retry_after]
      end
      return unless resp["X-RateLimit-Remaining"]

      @path_ratelimit_bucket[method + path] = resp["X-RateLimit-Bucket"]
      @current_ratelimits[resp["X-RateLimit-Bucket"]] = {
        remaining: resp["X-RateLimit-Remaining"].to_i,
        reset_at: Time.now.to_f + resp["X-RateLimit-Reset-After"].to_f,
      }
    end
  end
end

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
discorb-0.13.3 lib/discorb/rate_limit.rb
discorb-0.13.2 lib/discorb/rate_limit.rb
discorb-0.13.1 lib/discorb/rate_limit.rb
discorb-0.13.0 lib/discorb/rate_limit.rb