prop 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +4 -7
- data/VERSION +1 -1
- data/lib/prop.rb +1 -1
- data/prop.gemspec +3 -8
- data/test/test_prop.rb +8 -8
- metadata +9 -10
data/README.rdoc
CHANGED
@@ -15,9 +15,9 @@ To get going with Prop you first define the read and write operations. These def
|
|
15
15
|
|
16
16
|
You can choose to rely on a database or Moneta or Redis or whatever you'd like to use for transient storage. Prop does not do any sort of clean up of its key space, so you would have to implement that manually should you be using anything but an LRU cache.
|
17
17
|
|
18
|
-
Once the read and write operations are defined, you can optionally define
|
18
|
+
Once the read and write operations are defined, you can optionally define thresholds. If for example, you want to have a threshold on accepted emails per hour from a given user, you could define a threshold and interval (in seconds) for this like so:
|
19
19
|
|
20
|
-
Prop.
|
20
|
+
Prop.configure(:mails_per_hour, :threshold => 100, :interval => 1.hour)
|
21
21
|
|
22
22
|
You can now put the throttle to work with this values, by passing the "handle" to the respective methods in Prop:
|
23
23
|
|
@@ -50,7 +50,7 @@ If the throttle! method gets called more than "threshold" times within "interval
|
|
50
50
|
THROTTLE_MESSAGES[:login] = "Too many invalid login attempts. Try again later."
|
51
51
|
|
52
52
|
rescue_from Prop::RateLimitExceededError do |exception|
|
53
|
-
render :status => 403, :message => THROTTLE_MESSAGES[exception.handle]
|
53
|
+
render :status => 403, :message => I18n.t(THROTTLE_MESSAGES[exception.handle])
|
54
54
|
end
|
55
55
|
|
56
56
|
You can chose to override the threshold for a given key:
|
@@ -72,7 +72,7 @@ The default (and smallest possible) increment is 1, you can set that to any inte
|
|
72
72
|
Prop uses the interval to define a window of time using simple div arithmetic. This means that it's a worst case throttle that will allow up to 2 times the specified requests within the specified interval.
|
73
73
|
|
74
74
|
== Note on Patches/Pull Requests
|
75
|
-
|
75
|
+
|
76
76
|
* Fork the project.
|
77
77
|
* Make your feature addition or bug fix.
|
78
78
|
* Add tests for it. This is important so I don't break it in a
|
@@ -81,6 +81,3 @@ Prop uses the interval to define a window of time using simple div arithmetic. T
|
|
81
81
|
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
82
82
|
* Send me a pull request. Bonus points for topic branches.
|
83
83
|
|
84
|
-
== Copyright
|
85
|
-
|
86
|
-
Copyright (c) 2010 Morten Primdahl. See LICENSE for details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
data/lib/prop.rb
CHANGED
@@ -29,7 +29,7 @@ class Prop
|
|
29
29
|
self.writer = blk
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
32
|
+
def configure(handle, defaults)
|
33
33
|
raise RuntimeError.new("Invalid threshold setting") unless defaults[:threshold].to_i > 0
|
34
34
|
raise RuntimeError.new("Invalid interval setting") unless defaults[:interval].to_i > 0
|
35
35
|
|
data/prop.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{prop}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.6.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Morten Primdahl"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-08-18}
|
13
13
|
s.description = %q{A gem for implementing rate limiting}
|
14
14
|
s.email = %q{morten@zendesk.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -30,15 +30,10 @@ Gem::Specification.new do |s|
|
|
30
30
|
]
|
31
31
|
s.homepage = %q{http://github.com/morten/prop}
|
32
32
|
s.require_paths = ["lib"]
|
33
|
-
s.rubygems_version = %q{1.
|
33
|
+
s.rubygems_version = %q{1.6.2}
|
34
34
|
s.summary = %q{Puts a cork in their requests}
|
35
|
-
s.test_files = [
|
36
|
-
"test/helper.rb",
|
37
|
-
"test/test_prop.rb"
|
38
|
-
]
|
39
35
|
|
40
36
|
if s.respond_to? :specification_version then
|
41
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
42
37
|
s.specification_version = 3
|
43
38
|
|
44
39
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
data/test/test_prop.rb
CHANGED
@@ -15,16 +15,16 @@ class TestProp < Test::Unit::TestCase
|
|
15
15
|
context "#defaults" do
|
16
16
|
should "raise errors on invalid configuation" do
|
17
17
|
assert_raises(RuntimeError) do
|
18
|
-
Prop.
|
18
|
+
Prop.configure :hello_there, :threshold => 20, :interval => 'hello'
|
19
19
|
end
|
20
20
|
|
21
21
|
assert_raises(RuntimeError) do
|
22
|
-
Prop.
|
22
|
+
Prop.configure :hello_there, :threshold => 'wibble', :interval => 100
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
should "result in a default handle" do
|
27
|
-
Prop.
|
27
|
+
Prop.configure :hello_there, :threshold => 4, :interval => 10
|
28
28
|
4.times do |i|
|
29
29
|
assert_equal (i + 1), Prop.throttle!(:hello_there, 'some key')
|
30
30
|
end
|
@@ -34,7 +34,7 @@ class TestProp < Test::Unit::TestCase
|
|
34
34
|
end
|
35
35
|
|
36
36
|
should "create a handle accepts various cache key types" do
|
37
|
-
Prop.
|
37
|
+
Prop.configure :hello_there, :threshold => 4, :interval => 10
|
38
38
|
assert_equal 1, Prop.throttle!(:hello_there, 5)
|
39
39
|
assert_equal 2, Prop.throttle!(:hello_there, 5)
|
40
40
|
assert_equal 1, Prop.throttle!(:hello_there, '6')
|
@@ -46,7 +46,7 @@ class TestProp < Test::Unit::TestCase
|
|
46
46
|
|
47
47
|
context "#reset" do
|
48
48
|
setup do
|
49
|
-
Prop.
|
49
|
+
Prop.configure :hello, :threshold => 10, :interval => 10
|
50
50
|
|
51
51
|
5.times do |i|
|
52
52
|
assert_equal (i + 1), Prop.throttle!(:hello)
|
@@ -68,7 +68,7 @@ class TestProp < Test::Unit::TestCase
|
|
68
68
|
|
69
69
|
context "#throttled?" do
|
70
70
|
should "return true once the threshold has been reached" do
|
71
|
-
Prop.
|
71
|
+
Prop.configure(:hello, :threshold => 2, :interval => 10)
|
72
72
|
Prop.throttle!(:hello)
|
73
73
|
assert !Prop.throttled?(:hello)
|
74
74
|
Prop.throttle!(:hello)
|
@@ -96,7 +96,7 @@ class TestProp < Test::Unit::TestCase
|
|
96
96
|
end
|
97
97
|
|
98
98
|
should "not increment the counter beyond the threshold" do
|
99
|
-
Prop.
|
99
|
+
Prop.configure(:hello, :threshold => 5, :interval => 1)
|
100
100
|
10.times do |i|
|
101
101
|
Prop.throttle!(:hello) rescue nil
|
102
102
|
end
|
@@ -105,7 +105,7 @@ class TestProp < Test::Unit::TestCase
|
|
105
105
|
end
|
106
106
|
|
107
107
|
should "support custom increments" do
|
108
|
-
Prop.
|
108
|
+
Prop.configure(:hello, :threshold => 100, :interval => 10)
|
109
109
|
|
110
110
|
Prop.throttle!(:hello)
|
111
111
|
Prop.throttle!(:hello)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 7
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 6
|
9
|
+
- 0
|
10
|
+
version: 0.6.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Morten Primdahl
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-08-18 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -98,10 +98,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
98
|
requirements: []
|
99
99
|
|
100
100
|
rubyforge_project:
|
101
|
-
rubygems_version: 1.
|
101
|
+
rubygems_version: 1.6.2
|
102
102
|
signing_key:
|
103
103
|
specification_version: 3
|
104
104
|
summary: Puts a cork in their requests
|
105
|
-
test_files:
|
106
|
-
|
107
|
-
- test/test_prop.rb
|
105
|
+
test_files: []
|
106
|
+
|