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 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
  - - ">="