glutton_ratelimit 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document CHANGED
@@ -1,5 +1,5 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/LICENSE CHANGED
@@ -1,24 +1,24 @@
1
- This is free and unencumbered software released into the public domain.
2
-
3
- Anyone is free to copy, modify, publish, use, compile, sell, or
4
- distribute this software, either in source code form or as a compiled
5
- binary, for any purpose, commercial or non-commercial, and by any
6
- means.
7
-
8
- In jurisdictions that recognize copyright laws, the author or authors
9
- of this software dedicate any and all copyright interest in the
10
- software to the public domain. We make this dedication for the benefit
11
- of the public at large and to the detriment of our heirs and
12
- successors. We intend this dedication to be an overt act of
13
- relinquishment in perpetuity of all present and future rights to this
14
- software under copyright law.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
- IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
- OTHER DEALINGS IN THE SOFTWARE.
23
-
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
24
  For more information, please refer to <http://unlicense.org/>
@@ -1,125 +1,130 @@
1
- = glutton_ratelimit
2
-
3
- A Ruby library for limiting the number of times a method can be invoked within a specified time period.
4
-
5
- The rate-limiting is simple if somewhat naïve. Throttled methods are blocked using sleep.
6
-
7
- == Use Cases
8
-
9
- You might wish to use this library to throttle code that:
10
-
11
- * Accesses a 3rd-party API that imposes a maximum rate-limit.
12
- * Scrapes data from any website where rapid repeated access is banned.
13
-
14
- For example, EchoNest API requests need to be limited to 120 every minute.
15
-
16
- == Types of Limiting
17
-
18
- There are two types of rate limiting provided by this library:
19
-
20
- * Bursty Token Bucket Limiting (GluttonRatelimit::BurstyTokenBucket)
21
- * Average Throttle Limiting (GluttonRatelimit::AveragedThrottle)
22
-
23
- === Bursty Token Bucket
24
-
25
- If executions are limited to n times per m seconds then:
26
-
27
- 1. n executions will be allowed immediately.
28
- 2. Before the next execution the process will sleep for the remainder of the m second time period.
29
- 3. The process is repeated.
30
-
31
- The amount of time slept in step 2 will depend on how long the n executions took in step 1.
32
-
33
- === Average Throttle
34
-
35
- If executions are limited to n times per m seconds then:
36
-
37
- 1. The first execution will occur immediately.
38
- 2. Before each of the remaining n-1 executions the process will attempt to sleep so that the executions are evenly spaced within the m second time period.
39
- 3. The process is repeated.
40
-
41
- The amount of time slept before each execution will depend on the time period m and the average elapsed time of each execution.
42
-
43
- == Instance Method Limiting Example
44
-
45
- The rate_limit method can be used at the end of a class definition to limit specific instance methods.
46
-
47
- class LimitInstanceMethod
48
- # The class must be extended to permit limiting.
49
- extend GluttonRatelimit
50
-
51
- def initialize
52
- @start = Time.now
53
- end
54
-
55
- def limit_me
56
- puts "#{Time.now - @start}"
57
- end
58
-
59
- # Throttle the limit_me method to six executions every six seconds.
60
- rate_limit :limit_me, 6, 6
61
- end
62
-
63
- t = LimitInstanceMethod.new
64
-
65
- 10.times { t.limit_me }
66
-
67
- When using the rate_limit method the limiting defaults to GluttonRatelimit::AveragedThrottle. Token Bucket limiting can also be specified:
68
-
69
- rate_limite :limit_me, 6, 6, GluttonRatelimit::BurstyTokenBucket
70
-
71
- == Simple Manual Limiting Example
72
-
73
- Chunks of code can also be manually throttled using the wait method of a specific GluttonRatelimit object.
74
-
75
- # Maximum of twelve executions every five seconds.
76
- rl = GluttonRatelimit::BurstyTokenBucket.new 12, 5
77
-
78
- 25.times do
79
- # BurstyTokenBucket will allow for a full burst of executions followed by a pause.
80
- rl.wait
81
- # Simulating a constant-time task:
82
- sleep 0.1
83
- end
84
-
85
- # Maximum of six executions every six seconds.
86
- rl = GluttonRatelimit::AveragedThrottle.new 6, 6
87
- 13.times do
88
- # AverageThrottle will attempt to evenly space executions within the allowed period.
89
- rl.wait
90
- # Simulating a 0 to 1 second random-time task:
91
- sleep rand
92
- end
93
-
94
- == More Examples
95
-
96
- More examples can be found within the examples folder.
97
-
98
- == Warnings
99
-
100
- Before using the library you should be aware of the following warnings.
101
-
102
- === Short Tasks and AveragedThrottle
103
-
104
- The inaccuracy of Ruby's sleep method may cause timing issues with the AveragedThrottle limiting. Specifically, the limiting accuracy may be slightly-off when trying to rate-limit quick methods (sub-millisecond tasks).
105
-
106
- See: http://codeidol.com/other/rubyckbk/Date-and-Time/Waiting-a-Certain-Amount-of-Time
107
-
108
- It is recommend that you use the BurstyTokenBucket limiting when throttling very short tasks.
109
-
110
- === Naive Throttling
111
-
112
- As mentioned above, throttling is accomplish by blocking script execution using sleep. There is no support for dropping or queuing throttled method invocations.
113
-
114
- This library is not thread safe.
115
-
116
- == Thanks
117
-
118
- Some of the algorithms were inspired by these discussions:
119
-
120
- * http://stackoverflow.com/questions/667508/whats-a-good-rate-limiting-algorithm
121
- * http://stackoverflow.com/questions/1407113/throttling-method-calls-to-m-requests-in-n-seconds
122
-
123
- == License
124
-
1
+ = glutton_ratelimit
2
+
3
+ A Ruby library for limiting the number of times a method can be invoked within a specified time period.
4
+
5
+ The rate-limiting is simple if somewhat naïve. Throttled methods are blocked using sleep.
6
+
7
+ == Use Cases
8
+
9
+ You might wish to use this library to throttle code that:
10
+
11
+ * Accesses a 3rd-party API that imposes a maximum rate-limit.
12
+ * Scrapes data from any website where rapid repeated access is banned.
13
+
14
+ For example, EchoNest API requests need to be limited to 120 every minute.
15
+
16
+ == Installation
17
+
18
+ sudo gem install glutton_ratelimit
19
+
20
+ The gem is hosted at: http://rubygems.org/gems/glutton_ratelimit
21
+
22
+ == Types of Limiting
23
+
24
+ There are two types of rate limiting provided by this library:
25
+
26
+ * Bursty Token Bucket Limiting (GluttonRatelimit::BurstyTokenBucket)
27
+ * Average Throttle Limiting (GluttonRatelimit::AveragedThrottle)
28
+
29
+ === Bursty Token Bucket
30
+
31
+ If executions are limited to n times per m seconds then:
32
+
33
+ 1. n executions will be allowed immediately.
34
+ 2. Before the next execution the process will sleep for the remainder of the m second time period.
35
+ 3. The process is repeated.
36
+
37
+ The amount of time slept in step 2 will depend on how long the n executions took in step 1.
38
+
39
+ === Average Throttle
40
+
41
+ If executions are limited to n times per m seconds then:
42
+
43
+ 1. The first execution will occur immediately.
44
+ 2. Before each of the remaining n-1 executions the process will attempt to sleep so that the executions are evenly spaced within the m second time period.
45
+ 3. The process is repeated.
46
+
47
+ The amount of time slept before each execution will depend on the time period m and the average elapsed time of each execution.
48
+
49
+ == Instance Method Limiting Example
50
+
51
+ The rate_limit method can be used at the end of a class definition to limit specific instance methods.
52
+
53
+ class LimitInstanceMethod
54
+ # The class must be extended to permit limiting.
55
+ extend GluttonRatelimit
56
+
57
+ def initialize
58
+ @start = Time.now
59
+ end
60
+
61
+ def limit_me
62
+ puts "#{Time.now - @start}"
63
+ end
64
+
65
+ # Throttle the limit_me method to six executions every six seconds.
66
+ rate_limit :limit_me, 6, 6
67
+ end
68
+
69
+ t = LimitInstanceMethod.new
70
+
71
+ 10.times { t.limit_me }
72
+
73
+ When using the rate_limit method the limiting defaults to GluttonRatelimit::AveragedThrottle. Token Bucket limiting can also be specified:
74
+
75
+ rate_limite :limit_me, 6, 6, GluttonRatelimit::BurstyTokenBucket
76
+
77
+ == Simple Manual Limiting Example
78
+
79
+ Chunks of code can also be manually throttled using the wait method of a specific GluttonRatelimit object.
80
+
81
+ # Maximum of twelve executions every five seconds.
82
+ rl = GluttonRatelimit::BurstyTokenBucket.new 12, 5
83
+ # BurstyTokenBucket will allow for a full burst of executions followed by a pause.
84
+
85
+ rl.times(25) do
86
+ # Simulating a constant-time task:
87
+ sleep 0.1
88
+ end
89
+
90
+ # Maximum of six executions every six seconds.
91
+ rl = GluttonRatelimit::AveragedThrottle.new 6, 6
92
+ # AverageThrottle will attempt to evenly space executions within the allowed period.
93
+
94
+ rl.times(13) do
95
+ # Simulating a 0 to 1 second random-time task:
96
+ sleep rand
97
+ end
98
+
99
+ == More Examples
100
+
101
+ More examples can be found within the examples folder.
102
+
103
+ == Warnings
104
+
105
+ Before using the library you should be aware of the following warnings.
106
+
107
+ === Short Tasks and AveragedThrottle
108
+
109
+ The inaccuracy of Ruby's sleep method may cause timing issues with the AveragedThrottle limiting. Specifically, the limiting accuracy may be slightly-off when trying to rate-limit quick methods (sub-millisecond tasks).
110
+
111
+ See: http://codeidol.com/other/rubyckbk/Date-and-Time/Waiting-a-Certain-Amount-of-Time
112
+
113
+ It is recommend that you use the BurstyTokenBucket limiting when throttling very short tasks.
114
+
115
+ === Naive Throttling
116
+
117
+ As mentioned above, throttling is accomplish by blocking script execution using sleep. There is no support for dropping or queuing throttled method invocations.
118
+
119
+ This library is not thread safe.
120
+
121
+ == Thanks
122
+
123
+ Some of the algorithms were inspired by these discussions:
124
+
125
+ * http://stackoverflow.com/questions/667508/whats-a-good-rate-limiting-algorithm
126
+ * http://stackoverflow.com/questions/1407113/throttling-method-calls-to-m-requests-in-n-seconds
127
+
128
+ == License
129
+
125
130
  This is free and unencumbered software released into the public domain. See LICENSE for details.
data/Rakefile CHANGED
@@ -1,52 +1,52 @@
1
- require 'rubygems'
2
- require 'rake'
3
-
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "glutton_ratelimit"
8
- gem.summary = %Q{Simple Ruby library for self-imposed rater-limiting.}
9
- gem.description = %Q{A Ruby library for limiting the number of times a method can be invoked within a specified time period.}
10
- gem.email = "stungeye@gmail.com"
11
- gem.homepage = "http://github.com/stungeye/glutton_ratelimit"
12
- gem.authors = ["Wally Glutton"]
13
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
- end
15
- Jeweler::GemcutterTasks.new
16
- rescue LoadError
17
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
18
- end
19
-
20
- require 'rake/testtask'
21
- Rake::TestTask.new(:test) do |test|
22
- test.libs << 'lib' << 'test'
23
- test.pattern = 'test/**/test_*.rb'
24
- test.verbose = true
25
- end
26
-
27
- begin
28
- require 'rcov/rcovtask'
29
- Rcov::RcovTask.new do |test|
30
- test.libs << 'test'
31
- test.pattern = 'test/**/test_*.rb'
32
- test.verbose = true
33
- end
34
- rescue LoadError
35
- task :rcov do
36
- abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
37
- end
38
- end
39
-
40
- task :test => :check_dependencies
41
-
42
- task :default => :test
43
-
44
- require 'rake/rdoctask'
45
- Rake::RDocTask.new do |rdoc|
46
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
-
48
- rdoc.rdoc_dir = 'rdoc'
49
- rdoc.title = "glutton_ratelimit #{version}"
50
- rdoc.rdoc_files.include('README*')
51
- rdoc.rdoc_files.include('lib/**/*.rb')
52
- end
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "glutton_ratelimit"
8
+ gem.summary = %Q{Simple Ruby library for self-imposed rater-limiting.}
9
+ gem.description = %Q{A Ruby library for limiting the number of times a method can be invoked within a specified time period.}
10
+ gem.email = "stungeye@gmail.com"
11
+ gem.homepage = "http://github.com/stungeye/glutton_ratelimit"
12
+ gem.authors = ["Wally Glutton"]
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ end
15
+ Jeweler::GemcutterTasks.new
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
18
+ end
19
+
20
+ require 'rake/testtask'
21
+ Rake::TestTask.new(:test) do |test|
22
+ test.libs << 'lib' << 'test'
23
+ test.pattern = 'test/**/test_*.rb'
24
+ test.verbose = true
25
+ end
26
+
27
+ begin
28
+ require 'rcov/rcovtask'
29
+ Rcov::RcovTask.new do |test|
30
+ test.libs << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+ rescue LoadError
35
+ task :rcov do
36
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
37
+ end
38
+ end
39
+
40
+ task :test => :check_dependencies
41
+
42
+ task :default => :test
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
+
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "glutton_ratelimit #{version}"
50
+ rdoc.rdoc_files.include('README*')
51
+ rdoc.rdoc_files.include('lib/**/*.rb')
52
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -1,34 +1,34 @@
1
- require 'rubygems'
2
- require 'glutton_ratelimit'
3
-
4
- class LimitInstanceMethods
5
- extend GluttonRatelimit
6
-
7
- def initialize
8
- @start = Time.now
9
- end
10
-
11
- def limit_me
12
- puts "#{Time.now - @start}"
13
- sleep 0.001
14
- end
15
-
16
- def cap_me
17
- puts "#{Time.now - @start}"
18
- sleep 0.001
19
- end
20
-
21
- rate_limit :limit_me, 6, 6
22
- rate_limit :cap_me, 6, 6, GluttonRatelimit::BurstyTokenBucket
23
- end
24
-
25
- t = LimitInstanceMethods.new
26
-
27
- puts "Six requests every 6 seconds (Averaged): "
28
- 13.times { t.limit_me }
29
- puts "Six requests every 6 seconds (Bursty): "
30
- 13.times { t.cap_me }
31
-
32
- # In both cases:
33
- # The 7th execution should occur after 6 seconds after the first.
1
+ require 'rubygems'
2
+ require 'glutton_ratelimit'
3
+
4
+ class LimitInstanceMethods
5
+ extend GluttonRatelimit
6
+
7
+ def initialize
8
+ @start = Time.now
9
+ end
10
+
11
+ def limit_me
12
+ puts "#{Time.now - @start}"
13
+ sleep 0.001
14
+ end
15
+
16
+ def cap_me
17
+ puts "#{Time.now - @start}"
18
+ sleep 0.001
19
+ end
20
+
21
+ rate_limit :limit_me, 6, 6
22
+ rate_limit :cap_me, 6, 6, GluttonRatelimit::BurstyTokenBucket
23
+ end
24
+
25
+ t = LimitInstanceMethods.new
26
+
27
+ puts "Six requests every 6 seconds (Averaged): "
28
+ 13.times { t.limit_me }
29
+ puts "Six requests every 6 seconds (Bursty): "
30
+ 13.times { t.cap_me }
31
+
32
+ # In both cases:
33
+ # The 7th execution should occur after 6 seconds after the first.
34
34
  # The 13th execution should occur after 12 seconds after the first.