lhc 10.4.2 → 10.4.3
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 +1 -0
- data/lhc.gemspec +1 -0
- data/lib/lhc/interceptors/throttle.rb +22 -2
- data/lib/lhc/version.rb +1 -1
- data/spec/interceptors/throttle/main_spec.rb +17 -1
- data/spec/spec_helper.rb +1 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a016cff9475c03c337aa44f8688b1499e6ea983a63f3d23d65bf638668ad54d8
|
4
|
+
data.tar.gz: 061122763aef50722147734b3fe1985427a657b761da635dd3a3e91f82acff52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27230061ee806b82ae5f566156460ff179d8b79089dd44fbe5ab493761edf4809165f7f69ff043a99f59a81eb123d603b1644d40116a2682cd4509d32dd6034a
|
7
|
+
data.tar.gz: 774fffe78afb5c755b17ec7c04740fd5681a130f4dbe074e19c926d7df863a7948ea6a5b23bc43124238fcb4133029f318547db94f3a5e862bcb8b9f915a7b40
|
data/README.md
CHANGED
@@ -862,6 +862,7 @@ options = {
|
|
862
862
|
provider: 'local.ch', # name of the provider under which throttling tracking is aggregated,
|
863
863
|
limit: { header: 'Rate-Limit-Limit' }, # either a hard-coded integer, or a hash pointing at the response header containing the limit value
|
864
864
|
remaining: { header: 'Rate-Limit-Remaining' }, # a hash pointing at the response header containing the current amount of remaining requests
|
865
|
+
expires: { header: 'Rate-Limit-Reset' } # a hash pointing at the response header containing the timestamp when the quota will reset
|
865
866
|
}
|
866
867
|
}
|
867
868
|
|
data/lhc.gemspec
CHANGED
@@ -33,6 +33,7 @@ Gem::Specification.new do |s|
|
|
33
33
|
s.add_development_dependency 'rspec-rails', '>= 3.0.0'
|
34
34
|
s.add_development_dependency 'rubocop', '~> 0.57.1'
|
35
35
|
s.add_development_dependency 'rubocop-rspec', '~> 1.26.0'
|
36
|
+
s.add_development_dependency 'timecop'
|
36
37
|
s.add_development_dependency 'webmock'
|
37
38
|
|
38
39
|
s.license = 'GPL-3'
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'active_support/duration'
|
4
|
+
|
3
5
|
class LHC::Throttle < LHC::Interceptor
|
4
6
|
|
5
7
|
class OutOfQuota < StandardError
|
@@ -24,7 +26,8 @@ class LHC::Throttle < LHC::Interceptor
|
|
24
26
|
self.class.track ||= {}
|
25
27
|
self.class.track[options.dig(:provider)] = {
|
26
28
|
limit: limit(options: options[:limit], response: response),
|
27
|
-
remaining: remaining(options: options[:remaining], response: response)
|
29
|
+
remaining: remaining(options: options[:remaining], response: response),
|
30
|
+
expires: expires(options: options[:expires], response: response)
|
28
31
|
}
|
29
32
|
end
|
30
33
|
|
@@ -33,7 +36,8 @@ class LHC::Throttle < LHC::Interceptor
|
|
33
36
|
def break_when_quota_reached!
|
34
37
|
options = request.options.dig(:throttle)
|
35
38
|
track = (self.class.track || {}).dig(options[:provider])
|
36
|
-
return if track.blank? || track[:remaining].blank? || track[:limit].blank?
|
39
|
+
return if track.blank? || track[:remaining].blank? || track[:limit].blank? || track[:expires].blank?
|
40
|
+
return if Time.zone.now > track[:expires]
|
37
41
|
# avoid floats by multiplying with 100
|
38
42
|
remaining = track[:remaining] * 100
|
39
43
|
limit = track[:limit]
|
@@ -58,4 +62,20 @@ class LHC::Throttle < LHC::Interceptor
|
|
58
62
|
end
|
59
63
|
end
|
60
64
|
end
|
65
|
+
|
66
|
+
def expires(options:, response:)
|
67
|
+
@expires ||= begin
|
68
|
+
if options.is_a?(Hash) && options[:header] && response.headers.present?
|
69
|
+
convert_expires(response.headers[options[:header]]&.to_i)
|
70
|
+
else
|
71
|
+
convert_expires(options)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def convert_expires(value)
|
77
|
+
if value.is_a?(Integer)
|
78
|
+
Time.zone.at(value).to_datetime
|
79
|
+
end
|
80
|
+
end
|
61
81
|
end
|
data/lib/lhc/version.rb
CHANGED
@@ -13,12 +13,14 @@ describe LHC::Throttle do
|
|
13
13
|
track: true,
|
14
14
|
limit: limit_options,
|
15
15
|
remaining: { header: 'Rate-Limit-Remaining' },
|
16
|
+
expires: { header: 'Rate-Limit-Reset' },
|
16
17
|
break: break_option
|
17
18
|
}
|
18
19
|
}
|
19
20
|
end
|
20
21
|
let(:limit_options) { { header: 'Rate-Limit-Limit' } }
|
21
22
|
let(:break_option) { false }
|
23
|
+
let(:expires_in) { (Time.zone.now + 1.hour).to_i }
|
22
24
|
|
23
25
|
before(:each) do
|
24
26
|
LHC::Throttle.track = nil
|
@@ -28,7 +30,8 @@ describe LHC::Throttle do
|
|
28
30
|
.to_return(
|
29
31
|
headers: {
|
30
32
|
'Rate-Limit-Limit' => limit,
|
31
|
-
'Rate-Limit-Remaining' => remaining
|
33
|
+
'Rate-Limit-Remaining' => remaining,
|
34
|
+
'Rate-Limit-Reset' => expires_in
|
32
35
|
}
|
33
36
|
)
|
34
37
|
end
|
@@ -87,4 +90,17 @@ describe LHC::Throttle do
|
|
87
90
|
end
|
88
91
|
end
|
89
92
|
end
|
93
|
+
|
94
|
+
context 'expires' do
|
95
|
+
let(:break_option) { '80%' }
|
96
|
+
|
97
|
+
it 'attempts another request if the quota expired' do
|
98
|
+
LHC.get('http://local.ch', options)
|
99
|
+
expect(-> {
|
100
|
+
LHC.get('http://local.ch', options)
|
101
|
+
}).to raise_error(LHC::Throttle::OutOfQuota, 'Reached predefined quota for local.ch')
|
102
|
+
Timecop.travel(Time.zone.now + 2.hours)
|
103
|
+
LHC.get('http://local.ch', options)
|
104
|
+
end
|
105
|
+
end
|
90
106
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lhc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 10.4.
|
4
|
+
version: 10.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- https://github.com/local-ch/lhc/contributors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-07-
|
11
|
+
date: 2019-07-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -150,6 +150,20 @@ dependencies:
|
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: 1.26.0
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: timecop
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
153
167
|
- !ruby/object:Gem::Dependency
|
154
168
|
name: webmock
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|