glutton_ratelimit 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,30 +1,32 @@
1
- require 'rubygems'
2
- require 'glutton_ratelimit'
3
-
4
- puts "Maximum of 12 executions every 5 seconds (Bursty):"
5
- rl = GluttonRatelimit::BurstyTokenBucket.new 12, 5
6
-
7
- start = Time.now
8
- 25.times do |n|
9
- # BurstyTokenBucket will allow for a full burst of executions followed by a pause.
10
- rl.wait
11
- puts "#{n+1} - #{Time.now - start}"
12
- # Simulating a constant-time task:
13
- sleep 0.1
14
- end
15
-
16
- # The 25th execution should occur after 10 seconds has elapsed.
17
-
18
- puts "Maximum of 3 executions every 3 seconds (Averaged):"
19
- rl = GluttonRatelimit::AveragedThrottle.new 3, 3
20
-
21
- start = Time.now
22
- 7.times do |n|
23
- # AverageThrottle will attempt to evenly space executions within the allowed period.
24
- rl.wait
25
- puts "#{n+1} - #{Time.now - start}"
26
- # Simulating a 0 to 1 second random-time task:
27
- sleep rand
28
- end
29
-
1
+ # $LOAD_PATH << File.dirname(__FILE__) +'/../lib'
2
+ require 'rubygems'
3
+ require 'glutton_ratelimit'
4
+
5
+ puts "Maximum of 12 executions every 5 seconds (Bursty):"
6
+ rl = GluttonRatelimit::BurstyTokenBucket.new 12, 5
7
+
8
+ start = Time.now
9
+ n = 0
10
+
11
+ rl.times(25) do
12
+ puts "#{n += 1} - #{Time.now - start}"
13
+ # Simulating a constant-time task:
14
+ sleep 0.1
15
+ end
16
+
17
+ # The 25th execution should occur after 10 seconds has elapsed.
18
+
19
+ puts "Maximum of 3 executions every 3 seconds (Averaged):"
20
+ rl = GluttonRatelimit::AveragedThrottle.new 3, 3
21
+ # AverageThrottle will attempt to evenly space executions within the allowed period.
22
+
23
+ start = Time.now
24
+ n = 0
25
+
26
+ rl.times(7) do
27
+ puts "#{n += 1} - #{Time.now - start}"
28
+ # Simulating a 0 to 1 second random-time task:
29
+ sleep rand
30
+ end
31
+
30
32
  # The 7th execution should occur after 6 seconds has elapsed.
@@ -1,64 +1,64 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = %q{glutton_ratelimit}
8
- s.version = "0.1.0"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Wally Glutton"]
12
- s.date = %q{2010-06-10}
13
- s.description = %q{A Ruby library for limiting the number of times a method can be invoked within a specified time period.}
14
- s.email = %q{stungeye@gmail.com}
15
- s.extra_rdoc_files = [
16
- "LICENSE",
17
- "README.rdoc"
18
- ]
19
- s.files = [
20
- ".document",
21
- ".gitignore",
22
- "LICENSE",
23
- "README.rdoc",
24
- "Rakefile",
25
- "VERSION",
26
- "examples/limit_instance_methods.rb",
27
- "examples/simple_manual.rb",
28
- "glutton_ratelimit.gemspec",
29
- "lib/glutton_ratelimit.rb",
30
- "lib/glutton_ratelimit/averaged_throttle.rb",
31
- "lib/glutton_ratelimit/bursty_ring_buffer.rb",
32
- "lib/glutton_ratelimit/bursty_token_bucket.rb",
33
- "test/helper.rb",
34
- "test/test_glutton_ratelimit_averaged_throttle.rb",
35
- "test/test_glutton_ratelimit_bursty_ring_buffer.rb",
36
- "test/test_glutton_ratelimit_bursty_token_bucket.rb",
37
- "test/testing_module.rb"
38
- ]
39
- s.homepage = %q{http://github.com/stungeye/glutton_ratelimit}
40
- s.rdoc_options = ["--charset=UTF-8"]
41
- s.require_paths = ["lib"]
42
- s.rubygems_version = %q{1.3.6}
43
- s.summary = %q{Simple Ruby library for self-imposed rater-limiting.}
44
- s.test_files = [
45
- "test/test_glutton_ratelimit_averaged_throttle.rb",
46
- "test/helper.rb",
47
- "test/test_glutton_ratelimit_bursty_ring_buffer.rb",
48
- "test/testing_module.rb",
49
- "test/test_glutton_ratelimit_bursty_token_bucket.rb",
50
- "examples/limit_instance_methods.rb",
51
- "examples/simple_manual.rb"
52
- ]
53
-
54
- if s.respond_to? :specification_version then
55
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
56
- s.specification_version = 3
57
-
58
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
59
- else
60
- end
61
- else
62
- end
63
- end
64
-
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{glutton_ratelimit}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Wally Glutton"]
12
+ s.date = %q{2010-06-10}
13
+ s.description = %q{A Ruby library for limiting the number of times a method can be invoked within a specified time period.}
14
+ s.email = %q{stungeye@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "examples/limit_instance_methods.rb",
27
+ "examples/simple_manual.rb",
28
+ "glutton_ratelimit.gemspec",
29
+ "lib/glutton_ratelimit.rb",
30
+ "lib/glutton_ratelimit/averaged_throttle.rb",
31
+ "lib/glutton_ratelimit/bursty_ring_buffer.rb",
32
+ "lib/glutton_ratelimit/bursty_token_bucket.rb",
33
+ "test/helper.rb",
34
+ "test/test_glutton_ratelimit_averaged_throttle.rb",
35
+ "test/test_glutton_ratelimit_bursty_ring_buffer.rb",
36
+ "test/test_glutton_ratelimit_bursty_token_bucket.rb",
37
+ "test/testing_module.rb"
38
+ ]
39
+ s.homepage = %q{http://github.com/stungeye/glutton_ratelimit}
40
+ s.rdoc_options = ["--charset=UTF-8"]
41
+ s.require_paths = ["lib"]
42
+ s.rubygems_version = %q{1.3.6}
43
+ s.summary = %q{Simple Ruby library for self-imposed rater-limiting.}
44
+ s.test_files = [
45
+ "test/test_glutton_ratelimit_averaged_throttle.rb",
46
+ "test/helper.rb",
47
+ "test/test_glutton_ratelimit_bursty_ring_buffer.rb",
48
+ "test/testing_module.rb",
49
+ "test/test_glutton_ratelimit_bursty_token_bucket.rb",
50
+ "examples/limit_instance_methods.rb",
51
+ "examples/simple_manual.rb"
52
+ ]
53
+
54
+ if s.respond_to? :specification_version then
55
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
56
+ s.specification_version = 3
57
+
58
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
59
+ else
60
+ end
61
+ else
62
+ end
63
+ end
64
+
@@ -1,29 +1,38 @@
1
- module GluttonRatelimit
2
-
3
- def rate_limit symbol, executions, time_period, rl_class = AveragedThrottle
4
- rl = rl_class.new executions, time_period
5
- old_symbol = "#{symbol}_old".to_sym
6
- alias_method old_symbol, symbol
7
- define_method symbol do |*args|
8
- rl.wait
9
- self.send old_symbol, *args
10
- end
11
- end
12
-
13
- private
14
- # All the other classes extend this parent and are therefore
15
- # constructed in the same manner.
16
- class ParentLimiter
17
- attr_reader :executions
18
-
19
- def initialize executions, time_period
20
- @executions = executions
21
- @time_period = time_period
22
- end
23
- end
24
- end
25
-
26
- dir = File.expand_path(File.dirname(__FILE__))
27
- require File.join(dir, "glutton_ratelimit", "bursty_ring_buffer")
28
- require File.join(dir, "glutton_ratelimit", "bursty_token_bucket")
29
- require File.join(dir, "glutton_ratelimit", "averaged_throttle")
1
+ module GluttonRatelimit
2
+
3
+ def rate_limit symbol, executions, time_period, rl_class = AveragedThrottle
4
+ rl = rl_class.new executions, time_period
5
+ old_symbol = "#{symbol}_old".to_sym
6
+ alias_method old_symbol, symbol
7
+ define_method symbol do |*args|
8
+ rl.wait
9
+ self.send old_symbol, *args
10
+ end
11
+ end
12
+
13
+ private
14
+ # All the other classes extend this parent and are therefore
15
+ # constructed in the same manner.
16
+ class ParentLimiter
17
+ attr_reader :executions
18
+
19
+ def initialize executions, time_period
20
+ @executions = executions
21
+ @time_period = time_period
22
+ end
23
+
24
+ def times(num, &block)
25
+ raise ArgumentError, "Code block expected" if not block
26
+ raise ArgumentError, "Parameter expected to be Fixnum but found a #{num.class}." unless num.class.equal?(Fixnum)
27
+ num.times do
28
+ wait
29
+ yield
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ dir = File.expand_path(File.dirname(__FILE__))
36
+ require File.join(dir, "glutton_ratelimit", "bursty_ring_buffer")
37
+ require File.join(dir, "glutton_ratelimit", "bursty_token_bucket")
38
+ require File.join(dir, "glutton_ratelimit", "averaged_throttle")
@@ -1,44 +1,44 @@
1
- module GluttonRatelimit
2
-
3
- class AveragedThrottle < ParentLimiter
4
-
5
- def reset_bucket
6
- @before_previous_execution = Time.now if @before_previous_execution.nil?
7
- @oldest_timestamp = Time.now
8
- @tokens = @executions
9
- @total_task_time = 0
10
- end
11
-
12
- def executed_this_period
13
- @executions - @tokens
14
- end
15
-
16
- def average_task_time
17
- @total_task_time.to_f / executed_this_period
18
- end
19
-
20
- def wait
21
- reset_bucket if @tokens.nil?
22
-
23
- now = Time.now
24
- delta_since_previous = now - @before_previous_execution
25
- @total_task_time += delta_since_previous
26
- remaining_time = @time_period - (now - @oldest_timestamp)
27
-
28
- if @tokens.zero?
29
- sleep(remaining_time) if remaining_time > 0
30
- reset_bucket
31
- elsif executed_this_period != 0
32
- throttle = (remaining_time.to_f + delta_since_previous) / (@tokens+1) - average_task_time
33
- sleep throttle if throttle > 0
34
- end
35
-
36
- @tokens -= 1
37
- @before_previous_execution = Time.now
38
- end
39
-
40
- end
41
-
42
- end
43
-
44
-
1
+ module GluttonRatelimit
2
+
3
+ class AveragedThrottle < ParentLimiter
4
+
5
+ def reset_bucket
6
+ @before_previous_execution = Time.now if @before_previous_execution.nil?
7
+ @oldest_timestamp = Time.now
8
+ @tokens = @executions
9
+ @total_task_time = 0
10
+ end
11
+
12
+ def executed_this_period
13
+ @executions - @tokens
14
+ end
15
+
16
+ def average_task_time
17
+ @total_task_time.to_f / executed_this_period
18
+ end
19
+
20
+ def wait
21
+ reset_bucket if @tokens.nil?
22
+
23
+ now = Time.now
24
+ delta_since_previous = now - @before_previous_execution
25
+ @total_task_time += delta_since_previous
26
+ remaining_time = @time_period - (now - @oldest_timestamp)
27
+
28
+ if @tokens.zero?
29
+ sleep(remaining_time) if remaining_time > 0
30
+ reset_bucket
31
+ elsif executed_this_period != 0
32
+ throttle = (remaining_time.to_f + delta_since_previous) / (@tokens+1) - average_task_time
33
+ sleep throttle if throttle > 0
34
+ end
35
+
36
+ @tokens -= 1
37
+ @before_previous_execution = Time.now
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
44
+
@@ -1,24 +1,24 @@
1
- module GluttonRatelimit
2
-
3
- class BurstyRingBuffer < ParentLimiter
4
-
5
- def oldest_timestamp
6
- @timestamps = Array.new executions, (Time.now - @time_period) if @timestamps.nil?
7
- @timestamps[0]
8
- end
9
-
10
- def current_timestamp= new_stamp
11
- @timestamps.push(new_stamp).shift
12
- end
13
-
14
- def wait
15
- delta = Time.now - oldest_timestamp
16
- sleep(@time_period - delta) if delta < @time_period
17
- self.current_timestamp = Time.now
18
- end
19
-
20
- end
21
-
22
- end
23
-
24
-
1
+ module GluttonRatelimit
2
+
3
+ class BurstyRingBuffer < ParentLimiter
4
+
5
+ def oldest_timestamp
6
+ @timestamps = Array.new executions, (Time.now - @time_period) if @timestamps.nil?
7
+ @timestamps[0]
8
+ end
9
+
10
+ def current_timestamp= new_stamp
11
+ @timestamps.push(new_stamp).shift
12
+ end
13
+
14
+ def wait
15
+ delta = Time.now - oldest_timestamp
16
+ sleep(@time_period - delta) if delta < @time_period
17
+ self.current_timestamp = Time.now
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+
24
+
@@ -1,26 +1,26 @@
1
- module GluttonRatelimit
2
-
3
- class BurstyTokenBucket < ParentLimiter
4
-
5
- def reset_bucket
6
- @oldest_timestamp = Time.now
7
- @tokens = @executions
8
- end
9
-
10
- def wait
11
- reset_bucket if @tokens.nil?
12
-
13
- if @tokens.zero?
14
- delta = Time.now - @oldest_timestamp
15
- sleep(@time_period - delta) if delta < @time_period
16
- reset_bucket
17
- end
18
-
19
- @tokens -= 1
20
- end
21
-
22
- end
23
-
24
- end
25
-
26
-
1
+ module GluttonRatelimit
2
+
3
+ class BurstyTokenBucket < ParentLimiter
4
+
5
+ def reset_bucket
6
+ @oldest_timestamp = Time.now
7
+ @tokens = @executions
8
+ end
9
+
10
+ def wait
11
+ reset_bucket if @tokens.nil?
12
+
13
+ if @tokens.zero?
14
+ delta = Time.now - @oldest_timestamp
15
+ sleep(@time_period - delta) if delta < @time_period
16
+ reset_bucket
17
+ end
18
+
19
+ @tokens -= 1
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+
26
+