ruby-limiter 1.1.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/.travis.yml +3 -3
- data/CHANGELOG.md +13 -0
- data/README.md +9 -3
- data/Rakefile +2 -1
- data/dev.yml +1 -1
- data/lib/limiter/mixin.rb +4 -4
- data/lib/limiter/rate_queue.rb +3 -1
- data/lib/limiter/version.rb +1 -1
- data/limiter.gemspec +2 -0
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 144e27e5e203e66c7d753c3da5bce267a514de2f32be74849e96104d6450efe6
|
4
|
+
data.tar.gz: 6ec690da1476b519f6cbb6b22ba921b2c8006db09a706553304c0077a692e553
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4568e49199cc0a518439c808bc28e3281bdc44994495a0bee5e379c40c0de29bf45deee1e55d16d4f80df86424f26411c2f8b0fe13af605d18f8eb4b08c61db
|
7
|
+
data.tar.gz: 385abafc6d5e638829c0cd278a311b1d997a5c2b41e1010ae4b46cac5772498906f5254ab44777d353f36ef7ca228ce134ee2d6b91ceae4310384c4d9d5809e7
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## v2.1.0
|
4
|
+
|
5
|
+
- add support to call a block when limiting takes place
|
6
|
+
|
7
|
+
## v2.0.1
|
8
|
+
|
9
|
+
- eliminate kwarg warning in ruby 2.7 (while still supporting 2.6)
|
10
|
+
|
11
|
+
## v2.0.0
|
12
|
+
|
13
|
+
- end support for ruby 2.3/2.4/2.5
|
14
|
+
- test on ruby 2.6/2.7/3.0 (using ruby 2.7 for development)
|
15
|
+
|
3
16
|
## v1.1.0
|
4
17
|
|
5
18
|
- using Process.clock_gettime(Process::CLOCK_MONOTONIC) instead of Time.now for improved accuracy
|
data/README.md
CHANGED
@@ -46,7 +46,10 @@ class Widget
|
|
46
46
|
|
47
47
|
# limit the rate we can call tick to 5 times per second
|
48
48
|
# when the rate has been exceeded, a call to tick will block until the rate limit would not be exceeded
|
49
|
-
|
49
|
+
# and the provided block will be executed
|
50
|
+
limit_method(:tick, rate: 5, interval: 1) do
|
51
|
+
puts 'Limit reached'
|
52
|
+
end
|
50
53
|
|
51
54
|
...
|
52
55
|
end
|
@@ -55,13 +58,16 @@ end
|
|
55
58
|
### Advanced Usage
|
56
59
|
|
57
60
|
In cases where the mixin is not appropriate the `RateQueue` class can be used directly. As in the mixin examples above,
|
58
|
-
the `interval` parameter is optional (and defaults to 1 minute).
|
61
|
+
the `interval` parameter is optional (and defaults to 1 minute). It is also possible
|
62
|
+
to provide the block to `RateQueue`, which will be executed on each limit hit (useful for metrics).
|
59
63
|
|
60
64
|
``` ruby
|
61
65
|
class Widget
|
62
66
|
def initialize
|
63
67
|
# create a rate-limited queue which allows 10000 operations per hour
|
64
|
-
@queue = Limiter::RateQueue.new(10000, interval: 3600)
|
68
|
+
@queue = Limiter::RateQueue.new(10000, interval: 3600) do
|
69
|
+
puts "Hit the limit, waiting"
|
70
|
+
end
|
65
71
|
end
|
66
72
|
|
67
73
|
def tick
|
data/Rakefile
CHANGED
data/dev.yml
CHANGED
data/lib/limiter/mixin.rb
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
module Limiter
|
4
4
|
module Mixin
|
5
|
-
def limit_method(method, rate:, interval: 60)
|
6
|
-
queue = RateQueue.new(rate, interval: interval)
|
5
|
+
def limit_method(method, rate:, interval: 60, &b)
|
6
|
+
queue = RateQueue.new(rate, interval: interval, &b)
|
7
7
|
|
8
8
|
mixin = Module.new do
|
9
|
-
define_method(method) do |*args|
|
9
|
+
define_method(method) do |*args, **options, &blk|
|
10
10
|
queue.shift
|
11
|
-
super(*args)
|
11
|
+
options.empty? ? super(*args, &blk) : super(*args, **options, &blk)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
data/lib/limiter/rate_queue.rb
CHANGED
@@ -4,13 +4,14 @@ module Limiter
|
|
4
4
|
class RateQueue
|
5
5
|
EPOCH = 0.0
|
6
6
|
|
7
|
-
def initialize(size, interval: 60)
|
7
|
+
def initialize(size, interval: 60, &blk)
|
8
8
|
@size = size
|
9
9
|
@interval = interval
|
10
10
|
|
11
11
|
@ring = Array.new(size, EPOCH)
|
12
12
|
@head = 0
|
13
13
|
@mutex = Mutex.new
|
14
|
+
@blk = blk
|
14
15
|
end
|
15
16
|
|
16
17
|
def shift
|
@@ -33,6 +34,7 @@ module Limiter
|
|
33
34
|
def sleep_until(time)
|
34
35
|
interval = time - clock.time
|
35
36
|
return unless interval.positive?
|
37
|
+
@blk.call if @blk
|
36
38
|
clock.sleep(interval)
|
37
39
|
end
|
38
40
|
|
data/lib/limiter/version.rb
CHANGED
data/limiter.gemspec
CHANGED
@@ -13,6 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.summary = 'Simple Ruby rate limiting mechanism.'
|
14
14
|
spec.homepage = 'https://github.com/Shopify/limiter'
|
15
15
|
spec.license = 'MIT'
|
16
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
|
16
17
|
|
17
18
|
if spec.respond_to?(:metadata)
|
18
19
|
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
@@ -29,6 +30,7 @@ Gem::Specification.new do |spec|
|
|
29
30
|
|
30
31
|
spec.add_development_dependency 'bundler'
|
31
32
|
spec.add_development_dependency 'minitest', '~> 5.0'
|
33
|
+
spec.add_development_dependency 'minitest-focus', '~> 1.3'
|
32
34
|
spec.add_development_dependency 'mocha', '~> 1.11'
|
33
35
|
spec.add_development_dependency 'rake', '~> 10.0'
|
34
36
|
spec.add_development_dependency 'rubocop', '~> 0.56'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-limiter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- S. Brent Faulkner
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '5.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest-focus
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: mocha
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,14 +133,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
119
133
|
requirements:
|
120
134
|
- - ">="
|
121
135
|
- !ruby/object:Gem::Version
|
122
|
-
version:
|
136
|
+
version: 2.6.0
|
123
137
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
138
|
requirements:
|
125
139
|
- - ">="
|
126
140
|
- !ruby/object:Gem::Version
|
127
141
|
version: '0'
|
128
142
|
requirements: []
|
129
|
-
rubygems_version: 3.
|
143
|
+
rubygems_version: 3.2.20
|
130
144
|
signing_key:
|
131
145
|
specification_version: 4
|
132
146
|
summary: Simple Ruby rate limiting mechanism.
|