prop 2.1.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ea6891496856bc79f150b138e0c771f613d2214d
4
- data.tar.gz: 93efa5eb27652eb0c8bb907f3d7439bd5d4f8260
3
+ metadata.gz: a5a9acb5c4023850aae92780dca0a51f4ec7e6cc
4
+ data.tar.gz: b237584c3a9d4e78d8f525d858bc8d1a7a6ecfc2
5
5
  SHA512:
6
- metadata.gz: 2690c81fcd19c6c292e7782f15347e0fcb80f3e60d19e34c073e4e0b4b7b20d7c83ca9eef7e9c0ffcf8bf87f42270171a7f96c68cddabff130e2ac88859ad01f
7
- data.tar.gz: aa0ae06e67099a0b782404aa559c45af195e2f51967a1004d71dea15d98d3f88341ca47833f337a2f8b86a52b6b89dab9eac7b0df548fd8a67ccc4876d5bf405
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]`:
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  require "prop/limiter"
2
3
  require "forwardable"
3
4
 
4
5
  module Prop
5
- VERSION = "2.1.1"
6
+ VERSION = "2.2.0"
6
7
 
7
8
  # Short hand for accessing Prop::Limiter methods
8
9
  class << self
@@ -1,4 +1,4 @@
1
- require 'prop/limiter'
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 increment(cache_key, options)
17
- increment = options.fetch(:increment, 1)
18
- raise ArgumentError, "Increment must be a Fixnum, was #{increment.class}" unless increment.is_a?(Fixnum)
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, increment) || (cache.write(cache_key, increment, raw: true) && increment) # WARNING: potential race condition
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
- if options.key?(:increment)
59
- raise ArgumentError.new(":increment must be zero or a positive Integer") if !options[:increment].is_a?(Fixnum) || options[:increment] < 0
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
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "digest/md5"
2
3
 
3
4
  module Prop
@@ -13,4 +14,4 @@ module Prop
13
14
  end
14
15
 
15
16
  end
16
- end
17
+ end
@@ -1,7 +1,6 @@
1
- require 'prop/limiter'
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 increment(cache_key, options)
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)
@@ -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.increment(cache_key, options)
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)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Prop
2
3
 
3
4
  # Convenience middleware that conveys the message configured on a Prop handle as well
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'prop/key'
2
3
 
3
4
  module Prop
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Prop
2
3
  class RateLimited < StandardError
3
4
  attr_accessor :handle, :cache_key, :retry_after, :description, :first_throttled
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.1.1
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-01-23 00:00:00.000000000 Z
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
  - - ">="