Class: FloodControl

Inherits:
Object
  • Object
show all
Defined in:
lib/flood.rb

Overview

Provides a means to limit events to a count/time ratio. This is a more or less straight port of the Perl Algorithm::FloodControl library by Vladi Belperchinov-Shabanski.

See README for more information and examples of use.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(max_events, interval) ⇒ FloodControl

Returns a new instance of FloodControl.



13
14
15
16
17
# File 'lib/flood.rb', line 13

def initialize(max_events, interval)
  @flood = Hash.new
  @max_events = max_events
  @interval = interval
end

Instance Attribute Details

#floodObject

Returns the value of attribute flood.



9
10
11
# File 'lib/flood.rb', line 9

def flood
  @flood
end

#intervalObject

Returns the value of attribute interval.



9
10
11
# File 'lib/flood.rb', line 9

def interval
  @interval
end

#max_eventsObject

Returns the value of attribute max_events.



11
12
13
# File 'lib/flood.rb', line 11

def max_events
  @max_events
end

Instance Method Details

#check(event = '', max_events = @max_events, interval = @interval) ⇒ Object

Check if an event can proceed.

If no event id is given as an argument, the name of the caller is used.

max_events and interval can be overridden on a per-call basis.

The return value is 0 if event can proceed, or a positive integer if the limit has been exceeded. The value represents the number of seconds to wait so the event will occur within the limit set.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/flood.rb', line 54

def check(event='',max_events=@max_events, interval=@interval)

  #provide event key if not supplied
  if (event == '')
    # TEST: is this unique?
    event = caller[0].gsub(/\s/,'')
    # print STDERR "EN: $en\n";
  end
  
  # make empty flood array for this event key
  @flood[event] ||= Array.new;  
  
  event_count = @flood[event].length;
  
  if( event_count >= max_events )
    # flood array has enough events to do real flood check
    ot = @flood[event][0];      # oldest event timestamp in the flood array
    tp = Time.now.to_i - ot; # time period between current and oldest event
  
    # now calculate time in seconds until next allowed event
    wait = ot + ( event_count * interval / max_events ) - Time.now.to_i
    if( wait > 0 )
      # positive number of seconds means flood in progress
      # event_count should be rejected or postponed
      # print "WARNING: next event will be allowed in $wait seconds\n";
      return wait;
    end

    # negative or 0 seconds means that event should be accepted
    # oldest event is removed from the flood array
    @flood[event].shift;

  end
  # flood array is not full or oldest event is already removed
  # so current event has to be added

  @flood[event].push(Time.now.to_i);
  # event is ok
  return 0
end

#reset(event = nil) ⇒ Object

Reset the event count for a given event, or if no argument supplied reset the event count for all events.



21
22
23
24
25
26
27
# File 'lib/flood.rb', line 21

def reset(event=nil)
  if event.nil?
    @flood.clear
  else
    @flood.delete(event)
  end
end

#storageObject

Get flood data



96
97
98
# File 'lib/flood.rb', line 96

def storage
  @flood
end

#storage=(flood) ⇒ Object

Set flood data



101
102
103
# File 'lib/flood.rb', line 101

def storage=(flood)
  @flood=flood
end