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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e1d081bbe01eadc3a60d41068a65bb5b5f5e8d8d44547e8c076b8e0e5f72307d
4
- data.tar.gz: e0c41de69f16e1146aa28227a67cebd278a6f203439bdd737aff1d8247522d2f
3
+ metadata.gz: a016cff9475c03c337aa44f8688b1499e6ea983a63f3d23d65bf638668ad54d8
4
+ data.tar.gz: 061122763aef50722147734b3fe1985427a657b761da635dd3a3e91f82acff52
5
5
  SHA512:
6
- metadata.gz: cfaafff18eea78de74559bc8d866be1d9bcc3666d69bd0ee9ed4eefc8da80b9a962a32e134dc1603299481ab1768f0f44f89b0154652ba2764faa9a08eb29e96
7
- data.tar.gz: 74f4d0d051992fe02bdb31bafa8291b002466981430ad118b89fab189334ff6824864ead2021f86a0c967d7097e3809e75d1ad69e3e83d0f423099929e3b452a
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
 
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LHC
4
- VERSION ||= '10.4.2'
4
+ VERSION ||= '10.4.3'
5
5
  end
@@ -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
@@ -3,5 +3,6 @@
3
3
  require 'pry'
4
4
  require 'webmock/rspec'
5
5
  require 'lhc'
6
+ require 'timecop'
6
7
 
7
8
  Dir[File.join(__dir__, "support/**/*.rb")].each { |f| require f }
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.2
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-22 00:00:00.000000000 Z
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