Sha256: a86d181037d64cf825695f567efa43abcdbd1043a9e61b8b950b608bd30c3c3c

Contents?: true

Size: 1.29 KB

Versions: 2

Compression:

Stored size: 1.29 KB

Contents

require 'pause/helper/timing'

module Pause
  class Analyzer
    include Pause::Helper::Timing

    # #check(action)
    #
    # @param action [Pause::Action]
    # @return [nil]  everything is fine
    # @return [false]  this action is already blocked
    # @return [Pause::RateLimitedEvent]  the action was blocked as a result of this check
    def check(action)
      return false if adapter.rate_limited?(action.scope, action.identifier)
      timestamp = period_marker(Pause.config.resolution, Time.now.to_i)
      set = adapter.key_history(action.scope, action.identifier)
      action.checks.each do |period_check|
        start_time = timestamp - period_check.period_seconds
        set.reverse.inject(0) do |sum, element|
          break if element.ts < start_time
          sum += element.count
          if sum >= period_check.max_allowed
            adapter.rate_limit!(action.scope, action.identifier, period_check.block_ttl)
            # Note that Time.now is different from period_marker(resolution, Time.now), which
            # rounds down to the nearest (resolution) seconds
            return Pause::RateLimitedEvent.new(action, period_check, sum, Time.now.to_i)
          end
          sum
        end
      end
      nil
    end

    private

    def adapter
      Pause.adapter
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
pause-0.2.1 lib/pause/analyzer.rb
pause-0.2.0 lib/pause/analyzer.rb