prop 2.3.0 → 2.4.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.
- checksums.yaml +5 -5
- data/README.md +3 -0
- data/lib/prop.rb +1 -1
- data/lib/prop/interval_strategy.rb +7 -3
- data/lib/prop/leaky_bucket_strategy.rb +3 -2
- data/lib/prop/limiter.rb +2 -3
- data/lib/prop/options.rb +13 -6
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 850a96785d6d002acd243a5edf5cca965bd46bd1
|
4
|
+
data.tar.gz: 9ffb56011562feb0d9cf2c5ab62705420d59d46e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8cfee5d2c8af78a8a9273bdc873ba83ee6bb81237ca7cb253fce98dbf6180cff96f1004759e5d2fc4ee8e01364dddfae7f4b94c3909f547b08bcd3b109c9d7d2
|
7
|
+
data.tar.gz: 61e6d22651a9017e827d34220511fd8dd6dc60acaa69908968082d71a0ee6926859c0509f08b12fdf5a4d4310f83b95d0cf7b4137f713323d70fb88defcd0bbc
|
data/README.md
CHANGED
@@ -37,6 +37,9 @@ Example: Limit on accepted emails per hour from a given user, by defining a thre
|
|
37
37
|
|
38
38
|
```ruby
|
39
39
|
Prop.configure(:mails_per_hour, threshold: 100, interval: 1.hour, description: "Mail rate limit exceeded")
|
40
|
+
|
41
|
+
# Block requests by setting threshold to 0
|
42
|
+
Prop.configure(:mails_per_hour, threshold: 0, interval: 1.hour, description: "All mail is blocked")
|
40
43
|
```
|
41
44
|
|
42
45
|
```ruby
|
data/lib/prop.rb
CHANGED
@@ -56,8 +56,8 @@ module Prop
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def validate_options!(options)
|
59
|
-
|
60
|
-
|
59
|
+
validate_threshold(options[:threshold], :threshold)
|
60
|
+
validate_interval(options[:interval], :interval)
|
61
61
|
|
62
62
|
amount = options[:increment] || options[:decrement]
|
63
63
|
if amount
|
@@ -67,7 +67,11 @@ module Prop
|
|
67
67
|
|
68
68
|
private
|
69
69
|
|
70
|
-
def
|
70
|
+
def validate_threshold(option, key)
|
71
|
+
raise ArgumentError.new("#{key.inspect} must be a non-negative Integer") if !option.is_a?(Integer) || option < 0
|
72
|
+
end
|
73
|
+
|
74
|
+
def validate_interval(option, key)
|
71
75
|
raise ArgumentError.new("#{key.inspect} must be a positive Integer") if !option.is_a?(Integer) || option <= 0
|
72
76
|
end
|
73
77
|
|
@@ -8,9 +8,10 @@ module Prop
|
|
8
8
|
def counter(cache_key, options)
|
9
9
|
bucket = Prop::Limiter.cache.read(cache_key) || zero_counter
|
10
10
|
now = Time.now.to_i
|
11
|
-
|
11
|
+
leak_rate = (now - bucket.fetch(:last_updated)) / options.fetch(:interval).to_f
|
12
|
+
leak_amount = leak_rate * options.fetch(:threshold)
|
12
13
|
|
13
|
-
bucket[:bucket] = [bucket.fetch(:bucket) - leak_amount, 0].max
|
14
|
+
bucket[:bucket] = [(bucket.fetch(:bucket) - leak_amount).to_i, 0].max
|
14
15
|
bucket[:last_updated] = now
|
15
16
|
bucket
|
16
17
|
end
|
data/lib/prop/limiter.rb
CHANGED
@@ -46,8 +46,7 @@ module Prop
|
|
46
46
|
#
|
47
47
|
# Raises Prop::RateLimited if the number if the threshold for this handle has been reached
|
48
48
|
def configure(handle, defaults)
|
49
|
-
|
50
|
-
raise ArgumentError.new("Invalid interval setting") unless defaults[:interval].to_i > 0
|
49
|
+
Prop::Options.validate_options!(defaults)
|
51
50
|
|
52
51
|
self.handles ||= {}
|
53
52
|
self.handles[handle] = defaults
|
@@ -56,7 +55,7 @@ module Prop
|
|
56
55
|
# Public: Disables Prop for a block of code
|
57
56
|
#
|
58
57
|
# block - a block of code within which Prop will not raise
|
59
|
-
def disabled(&
|
58
|
+
def disabled(&_block)
|
60
59
|
@disabled = true
|
61
60
|
yield
|
62
61
|
ensure
|
data/lib/prop/options.rb
CHANGED
@@ -12,17 +12,24 @@ module Prop
|
|
12
12
|
result = defaults.merge(params)
|
13
13
|
|
14
14
|
result[:key] = Prop::Key.normalize(key)
|
15
|
+
result[:strategy] = get_strategy(result)
|
15
16
|
|
16
|
-
result[:strategy]
|
17
|
+
result[:strategy].validate_options!(result)
|
18
|
+
result
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.validate_options!(options)
|
22
|
+
get_strategy(options).validate_options!(options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.get_strategy(options)
|
26
|
+
if leaky_bucket.include?(options[:strategy])
|
17
27
|
Prop::LeakyBucketStrategy
|
18
|
-
elsif
|
28
|
+
elsif options[:strategy] == nil
|
19
29
|
Prop::IntervalStrategy
|
20
30
|
else
|
21
|
-
|
31
|
+
options[:strategy] # allowing any new/unknown strategy to be used
|
22
32
|
end
|
23
|
-
|
24
|
-
result[:strategy].validate_options!(result)
|
25
|
-
result
|
26
33
|
end
|
27
34
|
|
28
35
|
def self.leaky_bucket
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Morten Primdahl
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -116,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
116
116
|
version: '0'
|
117
117
|
requirements: []
|
118
118
|
rubyforge_project:
|
119
|
-
rubygems_version: 2.
|
119
|
+
rubygems_version: 2.6.14.4
|
120
120
|
signing_key:
|
121
121
|
specification_version: 4
|
122
122
|
summary: Gem for implementing rate limits.
|