Sha256: a573e201936ccbb533cd1ed0a9c145240dad46954992b2491ab71409ca684a89
Contents?: true
Size: 1.64 KB
Versions: 1
Compression:
Stored size: 1.64 KB
Contents
# frozen_string_literal: true require 'yaml' require 'redis' class EasyThrottle DEFAULT_OPTIONS = { interval: 60, limit: 1, burst: 20 }.freeze LIMITS = { # 'endpointName' => { interval: 10, limit: 1, burst: 1 }, }.freeze def self.with_throttling(endpoint, prefix, options = DEFAULT_OPTIONS, &block) new(endpoint, prefix, options).with_throttling { block.call } end def initialize(endpoint, prefix, options = DEFAULT_OPTIONS) @config = YAML.load_file('lib/config.yml') @endpoint = endpoint @prefix = prefix @redis = Redis.new @options = LIMITS.fetch(endpoint, options) end def with_throttling(&block) retry_count ||= 0 result = nil loop do if pool result = block.call break else sleep 0.1 end end result rescue StandardError => e if e.code == 429 extend_key_duration retry end if e.code == 500 raise if (retry_count += 1) > 5 extend_key_duration retry end raise e end def pool max_ttl = (options[:burst] - 1) * options[:interval] * 1000 burst_ttl = redis.pttl(burst_key) burst_ttl = 0 if burst_ttl.negative? if burst_ttl <= max_ttl redis.psetex(burst_key, burst_ttl + options[:interval] * 1000, true) end end private attr_reader :redis, :endpoint, :prefix, :options def burst_key "#{prefix}:#{endpoint}:burst" end def extend_key_duration redis.psetex(burst_key, (options[:interval] + 1) * options[:burst] * 1000, true) end def constantize(str) str.split('::').inject(Object) do |mod, class_name| mod.const_get(class_name) end end end
Version data entries
1 entries across 1 versions & 1 rubygems
Version | Path |
---|---|
EasyThrottle-0.0.2 | lib/easy_throttle.rb |