prop 2.1.1 → 2.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.
- checksums.yaml +4 -4
- data/README.md +7 -0
- data/lib/prop.rb +2 -1
- data/lib/prop/interval_strategy.rb +10 -7
- data/lib/prop/key.rb +2 -1
- data/lib/prop/leaky_bucket_strategy.rb +5 -3
- data/lib/prop/limiter.rb +3 -2
- data/lib/prop/middleware.rb +1 -0
- data/lib/prop/options.rb +1 -0
- data/lib/prop/rate_limited.rb +1 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5a9acb5c4023850aae92780dca0a51f4ec7e6cc
|
4
|
+
data.tar.gz: b237584c3a9d4e78d8f525d858bc8d1a7a6ecfc2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dab07c90b327eff3b46f96f2b7324aaeb9f63f3888fb2c61ab46b10b0403366f2cddfdf493bfdec32ee0e678df6ae0f7bbf9aaae792e91106a620c51f436d76a
|
7
|
+
data.tar.gz: e47254422205e73130f9c604d613d0e6cf39105c11ff8757fc2967237e81745a9b2cce95424d2931ad733c3bc2413586379f7e4446e3b72feb1270032153fb88
|
data/README.md
CHANGED
@@ -157,6 +157,13 @@ Prop.configure(:execute_time, threshold: 10, interval: 1.minute)
|
|
157
157
|
Prop.throttle!(:execute_time, account.id, increment: (Benchmark.realtime { execute }).to_i)
|
158
158
|
```
|
159
159
|
|
160
|
+
Decrement can be used to for example throttle before an expensive action and then give quota back when some condition is met.
|
161
|
+
`:decrement` is only supported for `IntervalStrategy` for now
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
Prop.throttle!(:api_counts, request.remote_ip, decrement: 1)
|
165
|
+
```
|
166
|
+
|
160
167
|
## Optional configuration
|
161
168
|
|
162
169
|
You can add optional configuration to a prop and retrieve it using `Prop.configurations[:foo]`:
|
data/lib/prop.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
require 'prop/options'
|
3
3
|
require 'prop/key'
|
4
4
|
|
@@ -13,11 +13,13 @@ module Prop
|
|
13
13
|
Prop::Limiter.cache.read(cache_key).to_i
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
16
|
+
def change(cache_key, options)
|
17
|
+
amount = options.key?(:decrement) ?
|
18
|
+
-(options.fetch(:decrement)) :
|
19
|
+
options.fetch(:increment, 1)
|
20
|
+
raise ArgumentError, "Change amount must be a Fixnum, was #{amount.class}" unless amount.is_a?(Fixnum)
|
19
21
|
cache = Prop::Limiter.cache
|
20
|
-
cache.increment(cache_key,
|
22
|
+
cache.increment(cache_key, amount) || (cache.write(cache_key, amount, raw: true) && amount) # WARNING: potential race condition
|
21
23
|
end
|
22
24
|
|
23
25
|
def reset(cache_key)
|
@@ -55,8 +57,9 @@ module Prop
|
|
55
57
|
validate_positive_integer(options[:threshold], :threshold)
|
56
58
|
validate_positive_integer(options[:interval], :interval)
|
57
59
|
|
58
|
-
|
59
|
-
|
60
|
+
amount = options[:increment] || options[:decrement]
|
61
|
+
if amount
|
62
|
+
raise ArgumentError.new(":increment or :decrement must be zero or a positive Integer") if !amount.is_a?(Fixnum) || amount < 0
|
60
63
|
end
|
61
64
|
end
|
62
65
|
|
data/lib/prop/key.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
require 'prop/options'
|
3
3
|
require 'prop/key'
|
4
|
-
require 'prop/interval_strategy'
|
5
4
|
|
6
5
|
module Prop
|
7
6
|
class LeakyBucketStrategy
|
@@ -18,7 +17,10 @@ module Prop
|
|
18
17
|
|
19
18
|
# WARNING: race condition
|
20
19
|
# this increment is not atomic, so it might miss counts when used frequently
|
21
|
-
def
|
20
|
+
def change(cache_key, options)
|
21
|
+
# please open a PR if you know how to support this
|
22
|
+
raise ArgumentError, "decrement is not supported for LeakyBucketStrategy" if options.key?(:decrement)
|
23
|
+
|
22
24
|
counter = counter(cache_key, options)
|
23
25
|
counter[:bucket] += options.fetch(:increment, 1)
|
24
26
|
Prop::Limiter.cache.write(cache_key, counter)
|
data/lib/prop/limiter.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'prop/rate_limited'
|
2
3
|
require 'prop/key'
|
3
4
|
require 'prop/options'
|
@@ -145,7 +146,7 @@ module Prop
|
|
145
146
|
def _throttle(handle, key, cache_key, options)
|
146
147
|
return [false, @strategy.zero_counter] if disabled?
|
147
148
|
|
148
|
-
counter = @strategy.
|
149
|
+
counter = @strategy.change(cache_key, options)
|
149
150
|
|
150
151
|
if @strategy.compare_threshold?(counter, :>, options)
|
151
152
|
before_throttle_callback &&
|
@@ -164,7 +165,7 @@ module Prop
|
|
164
165
|
end
|
165
166
|
|
166
167
|
def disabled?
|
167
|
-
!!@disabled
|
168
|
+
defined?(@disabled) && !!@disabled
|
168
169
|
end
|
169
170
|
|
170
171
|
def prepare(handle, key, params)
|
data/lib/prop/middleware.rb
CHANGED
data/lib/prop/options.rb
CHANGED
data/lib/prop/rate_limited.rb
CHANGED
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.2.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: 2016-
|
11
|
+
date: 2016-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -108,7 +108,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
108
108
|
requirements:
|
109
109
|
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version: '0'
|
111
|
+
version: '2.0'
|
112
112
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
113
|
requirements:
|
114
114
|
- - ">="
|