Sha256: a68d9645cebe02762563bc907d27b3c719099688b22b249cb3f8d153959056bd

Contents?: true

Size: 1.75 KB

Versions: 1

Compression:

Stored size: 1.75 KB

Contents

require 'prop/limiter'
require 'prop/options'
require 'prop/key'

module Prop
  class IntervalStrategy
    class << self
      def counter(cache_key, options)
        Prop::Limiter.reader.call(cache_key).to_i
      end

      def increment(cache_key, options, counter)
        increment = options.fetch(:increment, 1)
        Prop::Limiter.writer.call(cache_key, counter + increment)
      end

      def reset(cache_key)
        Prop::Limiter.writer.call(cache_key, 0)
      end

      def at_threshold?(counter, options)
        counter >= options.fetch(:threshold)
      end

      # Builds the expiring cache key
      def build(options)
        key       = options.fetch(:key)
        handle    = options.fetch(:handle)
        interval  = options.fetch(:interval)

        window    = (Time.now.to_i / interval)
        cache_key = Prop::Key.normalize([ handle, key, window ])

        "prop/#{Digest::MD5.hexdigest(cache_key)}"
      end

      def threshold_reached(options)
        threshold = options.fetch(:threshold)

        "#{options[:handle]} threshold of #{threshold} tries per #{options[:interval]}s exceeded for key '#{options[:key].inspect}', hash #{options[:cache_key]}"
      end

      def validate_options!(options)
        validate_positive_integer(options[:threshold], :threshold)
        validate_positive_integer(options[:interval], :interval)

        if options.key?(:increment)
          raise ArgumentError.new(":increment must be zero or a positive Integer") if !options[:increment].is_a?(Fixnum) || options[:increment] < 0
        end
      end

      private

      def validate_positive_integer(option, key)
        raise ArgumentError.new("#{key.inspect} must be a positive Integer") if !option.is_a?(Fixnum) || option <= 0
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
prop-1.2.0 lib/prop/interval_strategy.rb