redis-throttler 0.1.5 → 0.1.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c3648bd744161a9c30693fd53fb7bfb490ab54f3
4
- data.tar.gz: 1b7c3424b04912da66ed591db45e14a36e518e5d
3
+ metadata.gz: aee41934ea93c01a4563339083e4c04267b0cd89
4
+ data.tar.gz: 134b60d1f35fdb047bf7cd195eb0ca7153d26ec9
5
5
  SHA512:
6
- metadata.gz: 7bff0a3c2299681c052da3d0333f6c7858ae5b689a2c434ead0e18de1bcfa83dbc94b9f241afb4509fe05c5eef3c2d5b9c5cd18cc0faf6b2aae0b20abd8f0bfa
7
- data.tar.gz: bf0eac98c7f1cff826f20c79330f135b4252d58d8b47b77ce45000e20521d0df3dffebd52450efd4abb1d330e0217c2c289d15600d426a8f27610cf3af6ee1cd
6
+ metadata.gz: 486543f3afa4f34f92263547babf2a20245e285e88bc8c013827c660ae43d2ab9be645c6342767b66e86d5d1dc4ef7cf12cd0cf795ce71dd18c422aed4eb2b4c
7
+ data.tar.gz: 14db1b9b171195d51bf0fc5af2954adee390a8f7dcb5eb7115c49802353cc072e8b3a19181b22f9823c39d8018918f62b75059da91479df0d4750a6fc02f9fd1
data/ChangeLog.md CHANGED
@@ -1,3 +1,11 @@
1
+ ### 0.1.6 / 2016-08-01:
2
+
3
+ * Add test specs
4
+
5
+ ### 0.1.5 / 2016-07-31
6
+
7
+ * Initial upload of lib:
8
+
1
9
  ### 0.1.0 / 2016-07-31
2
10
 
3
11
  * Initial release:
data/gemspec.yml CHANGED
@@ -14,4 +14,5 @@ development_dependencies:
14
14
  rake: ~> 10.0
15
15
  rspec: ~> 3.0
16
16
  rubygems-tasks: ~> 0.2
17
+ timecop: ~> 0.8
17
18
  yard: ~> 0.8
@@ -114,7 +114,7 @@ module RedisThrottler
114
114
  end
115
115
 
116
116
  def redis
117
- @redis ||= Redis.new(host: '192.168.99.100', port: 32771)
117
+ @redis ||= Redis.new(host: '192.168.99.100', port: 32768)
118
118
  end
119
119
  end
120
120
  end
@@ -18,29 +18,31 @@ module RedisThrottler
18
18
  threshold = opts[:for] || 900
19
19
  interval = opts[:interval] || 5
20
20
 
21
- limiter = RedisThrottler::Base.new("#{klass}:#{key}", bucket_interval: interval, bucket_span: threshold)
21
+ bucket_span = [interval, 600].max
22
+
23
+ throttler = RedisThrottler::Base.new("#{klass}:#{key}", bucket_interval: interval, bucket_span: bucket_span)
22
24
  @limits[key] = "#{subject.to_s} limit #{limit} per #{threshold} sec"
23
25
 
24
26
  # includes('?') will return true
25
- method = "#{key}_limiter"
27
+ method = "#{key}_throttler"
26
28
 
27
29
  %w(limits limits?).each do |string|
28
30
  define_singleton_method(string) { string.include?('?') || @limits }
29
- define_method(string) { string.include?('?') || @limits }
31
+ define_method(string) { string.include?('?') || self.class.instance_variable_get('@limits')}
30
32
  end
31
33
 
32
34
  # i used Procs because they don't complain about arity
33
35
  # these Procs will return a string to be evaluated in context
34
36
 
35
37
  methods = {
36
- :exceeded? => proc { |to_call| "#{method}.exceeded? \"#{to_call}\", threshold: #{limit}, interval: #{threshold}" },
38
+ :exceeded? => proc { |to_call, within| "#{method}.exceeded? \"#{to_call}\", threshold: #{limit}, interval: #{within}" },
37
39
  :increment => proc { |to_call| "#{method}.add(\"#{to_call}\")" },
38
40
  :count => proc { |to_call, within| "#{method}.count(\"#{to_call}\", #{within})" }
39
41
  }
40
42
 
41
43
  # define the class & instance methods
42
44
  # pass the id to access counters
43
- define_singleton_method(method) { limiter }
45
+ define_singleton_method(method) { throttler }
44
46
  define_method(method) { self.class.send method }
45
47
 
46
48
  methods.each do |magic, meth|
@@ -1,3 +1,3 @@
1
1
  module RedisThrottler
2
- VERSION = '0.1.5'
2
+ VERSION = '0.1.6'
3
3
  end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe TestClass do
4
+
5
+ it 'should be able to define throttle' do
6
+ expect(TestClass).to respond_to :throttle
7
+ end
8
+
9
+ it 'should have a throttler for defined throttle' do
10
+ expect(TestClass.logins_throttler.class).to eq(RedisThrottler::Base)
11
+ end
12
+
13
+ it 'should display limits as hash' do
14
+ expect(TestClass.limits).to be_a(Hash)
15
+ end
16
+
17
+ it 'should respond to limits? correctly' do
18
+ expect(TestClass.limits?).to eq(true)
19
+ end
20
+
21
+ it 'should be able to increment throttler by subject' do
22
+ TestClass.logins_increment('testid')
23
+ TestClass.logins_increment('testid')
24
+ expect(TestClass.logins_count('testid')).to eq(2)
25
+ end
26
+
27
+ it 'should responsd to exceeded? correctly' do
28
+ TestClass.logins_throttler.add('testid', 10)
29
+ expect(TestClass.logins_exceeded?('testid')).to eq(true)
30
+
31
+ TestClass.logins_throttler.add('testid2', 9)
32
+ expect(TestClass.logins_exceeded?('testid2')).to eq(false)
33
+ end
34
+
35
+ it 'should not be rate-limited after interval' do
36
+ expect(TestClass.logins_exceeded?('test3')).to eq(false)
37
+ 10.times { TestClass.logins_increment('test3') }
38
+ expect(TestClass.logins_exceeded?('test3')).to eq(true)
39
+ Timecop.travel(60) do
40
+ expect(TestClass.logins_exceeded?('test3')).to eq(false)
41
+ end
42
+ end
43
+
44
+ it 'should return counter value for subject within defined limits' do
45
+ 10.times { TestClass.logins_increment('test4') }
46
+ expect(TestClass.logins_count('test4')).to eq(TestClass.logins_throttler.count('test4', 60))
47
+ end
48
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Instace of TestClass' do
4
+ before do
5
+ @test = TestClass.new
6
+ end
7
+
8
+ it 'should have a throttler for defined throttle' do
9
+ expect(@test.logins_throttler.class).to eq(RedisThrottler::Base)
10
+ end
11
+
12
+ it 'should display limits as hash' do
13
+ expect(@test.limits).to be_a(Hash)
14
+ end
15
+
16
+ it 'should respond to limits? correctly' do
17
+ expect(@test.limits?).to eq(true)
18
+ end
19
+
20
+ it 'should be able to increment throttler by subject' do
21
+ @test.logins_increment
22
+ @test.logins_increment
23
+ expect(@test.logins_count).to eq(2)
24
+ end
25
+
26
+ it 'should responsd to exceeded? correctly' do
27
+ 10.times do
28
+ @test.logins_increment
29
+ end
30
+ expect(@test.logins_exceeded?).to eq(true)
31
+ end
32
+
33
+ it 'should not be rate-limited after interval' do
34
+ Timecop.travel(60) do
35
+ expect(@test.logins_exceeded?).to eq(false)
36
+ end
37
+ end
38
+
39
+ it 'should return counter value for subject within defined limits' do
40
+ expect(@test.logins_count).to eq(TestClass.logins_count(@test.id))
41
+ end
42
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,17 @@
1
1
  require 'rspec'
2
2
  require 'redis-throttler'
3
3
  require 'redis-throttler/base'
4
+ require 'timecop'
4
5
 
6
+ class TestClass
7
+ include RedisThrottler
8
+ throttle :logins, limit: 10, for: 60
9
+
10
+ def initialize
11
+ @id = 1234
12
+ end
13
+
14
+ def id
15
+ @id
16
+ end
17
+ end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe RedisThrottler do
3
+ describe RedisThrottler::Base do
4
4
 
5
5
  before do
6
6
  @rl = RedisThrottler::Base.new('test')
@@ -24,18 +24,18 @@ describe RedisThrottler do
24
24
  end
25
25
 
26
26
  it 'should be able to add to the count for a given subject' do
27
- @rl.add("value1")
28
- @rl.add("value1")
27
+ @rl.add('value1')
28
+ @rl.add('value1')
29
29
  expect(@rl.count('value1', 1)).to eq(2)
30
- expect(@rl.count("value2", 1)).to eq(0)
31
- # Timecop.travel(600) do
32
- # expect(@rl.count("value1", 1)).to eq(0)
33
- # end
30
+ expect(@rl.count('value2', 1)).to eq(0)
31
+ Timecop.travel(60) do
32
+ expect(@rl.count('value1', 1)).to eq(0)
33
+ end
34
34
  end
35
35
 
36
36
  it 'should be able to add to the count by more than 1' do
37
- @rl.add("value1", 3)
38
- expect(@rl.count("value1", 1)).to eq(3)
37
+ @rl.add('value1', 3)
38
+ expect(@rl.count('value1', 1)).to eq(3)
39
39
  end
40
40
 
41
41
  it 'should be able to add to the count for a non-string subject' do
@@ -43,9 +43,9 @@ describe RedisThrottler do
43
43
  @rl.add(123)
44
44
  expect(@rl.count(123, 1)).to eq(2)
45
45
  expect(@rl.count(124, 1)).to eq(0)
46
- # Timecop.travel(10) do
47
- # expect(@rl.count(123, 1)).to eq(0)
48
- # end
46
+ Timecop.travel(10) do
47
+ expect(@rl.count(123, 1)).to eq(0)
48
+ end
49
49
  end
50
50
 
51
51
  it 'should return counter value' do
@@ -69,29 +69,29 @@ describe RedisThrottler do
69
69
  expect(@rl.within_bounds?("value1", {:threshold => 10, :interval => 30})).to be false
70
70
  end
71
71
 
72
- # it "accept a threshold and a block that gets executed once it's below the threshold" do
73
- # expect(@rl.count("key", 30)).to eq(0)
74
- # 31.times do
75
- # @rl.add("key")
76
- # end
77
- # expect(@rl.count("key", 30)).to eq(31)
78
- #
79
- # @value = nil
80
- # expect do
81
- # timeout(1) do
82
- # @rl.exec_within_threshold("key", {:threshold => 30, :interval => 30}) do
83
- # @value = 2
84
- # end
85
- # end
86
- # end.to raise_error(Timeout::Error)
87
- # expect(@value).to be nil
88
- # # Timecop.travel(40) do
89
- # # @rl.exec_within_threshold("key", {:threshold => 30, :interval => 30}) do
90
- # # @value = 1
91
- # # end
92
- # # end
93
- # # expect(@value).to be 1
94
- # end
72
+ it "accept a threshold and a block that gets executed once it's below the threshold" do
73
+ expect(@rl.count("key", 30)).to eq(0)
74
+ 31.times do
75
+ @rl.add("key")
76
+ end
77
+ expect(@rl.count("key", 30)).to eq(31)
78
+
79
+ @value = nil
80
+ expect do
81
+ Timeout.timeout(1) do
82
+ @rl.exec_within_threshold("key", {:threshold => 30, :interval => 30}) do
83
+ @value = 2
84
+ end
85
+ end
86
+ end.to raise_error(Timeout::Error)
87
+ expect(@value).to be nil
88
+ Timecop.travel(40) do
89
+ @rl.exec_within_threshold("key", {:threshold => 30, :interval => 30}) do
90
+ @value = 1
91
+ end
92
+ end
93
+ expect(@value).to be 1
94
+ end
95
95
 
96
96
  it 'counts correclty if bucket_span equals count-interval ' do
97
97
  @rl = RedisThrottler::Base.new('key', {:bucket_span => 10, bucket_interval: 1})
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-throttler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Surdam
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0.2'
83
+ - !ruby/object:Gem::Dependency
84
+ name: timecop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.8'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.8'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: yard
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -118,6 +132,8 @@ files:
118
132
  - lib/redis-throttler/model.rb
119
133
  - lib/redis-throttler/version.rb
120
134
  - redis-throttler.gemspec
135
+ - spec/model_spec.rb
136
+ - spec/object_spec.rb
121
137
  - spec/spec_helper.rb
122
138
  - spec/throttler_spec.rb
123
139
  homepage: https://github.com/esurdam/redis-throttler#readme