dhc 2.0.1 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/README.md +25 -0
- data/dhc.gemspec +1 -1
- data/lib/dhc/interceptors/caching.rb +2 -2
- data/lib/dhc/interceptors/throttle.rb +81 -44
- data/lib/dhc/logger.rb +30 -0
- data/lib/dhc/rspec.rb +1 -1
- data/lib/dhc/version.rb +1 -1
- data/lib/dhc.rb +1 -0
- data/spec/interceptors/caching/multilevel_cache_spec.rb +12 -12
- data/spec/interceptors/throttle/main_spec.rb +4 -4
- data/spec/interceptors/throttle/manually_spec.rb +110 -0
- data/spec/interceptors/throttle/reset_track_spec.rb +0 -1
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f70dd2da0d8ec740cf21499fc95ba815a73730c2e1c6a4b8cfef6ff18eef0ce
|
4
|
+
data.tar.gz: b0773620c07f30f040439d1c56c7a144ee2f144eb0d987d885aec2b940367b6a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c652d89a8d1dcbeadf72472322881ce136692d1b51630c61f4cf0b058ff96d9ded1345c80238fa5d46599d494328ebaecc007a915283eae1971efe89de8cea6
|
7
|
+
data.tar.gz: 9f71766d909205e3771cd2cfd65130458ac6a73bf35119bd6edf83f1de1ecba418611b66544affd4572b4b275641875d6ae6507fd4a4d07ad1609ae263ff1694
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -854,6 +854,8 @@ If it raises, it forwards the request and response object to rollbar, which cont
|
|
854
854
|
|
855
855
|
The throttle interceptor allows you to raise an exception if a predefined quota of a provider request limit is reached in advance.
|
856
856
|
|
857
|
+
The throttle state (tracker) is stored in Rails.cache.
|
858
|
+
|
857
859
|
```ruby
|
858
860
|
DHC.configure do |c|
|
859
861
|
c.interceptors = [DHC::Throttle]
|
@@ -889,10 +891,33 @@ DHC.get('http://depay.fi', options)
|
|
889
891
|
* `remaining`:
|
890
892
|
* a hash pointing at the response header containing the current amount of remaining requests
|
891
893
|
* a proc that receives the response as argument and returns the current amount of remaining requests
|
894
|
+
* not set: will track remaining by counting down limit until `expires`
|
892
895
|
* `expires`:
|
893
896
|
* a hash pointing at the response header containing the timestamp when the quota will reset
|
894
897
|
* a proc that receives the response as argument and returns the timestamp when the quota will reset
|
898
|
+
* an ActiveSupport::Duration e.g. 1.minute
|
899
|
+
|
900
|
+
Example for throttling manually without relating to any information in the response:
|
895
901
|
|
902
|
+
```ruby
|
903
|
+
options = {
|
904
|
+
throttle: {
|
905
|
+
track: true,
|
906
|
+
break: '80%',
|
907
|
+
provider: 'depay.fi',
|
908
|
+
limit: 100,
|
909
|
+
expires: 1.minute
|
910
|
+
}
|
911
|
+
}
|
912
|
+
|
913
|
+
DHC.get('http://depay.fi', options)
|
914
|
+
```
|
915
|
+
|
916
|
+
Will reset every minute, and will allow up to 80 requests per minute. The 81st request attempt within a minute will raise:
|
917
|
+
|
918
|
+
```ruby
|
919
|
+
DHC::Throttle::OutOfQuota: Reached predefined quota for depay.fi
|
920
|
+
```
|
896
921
|
|
897
922
|
#### Zipkin
|
898
923
|
|
data/dhc.gemspec
CHANGED
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
|
|
28
28
|
|
29
29
|
s.add_development_dependency 'prometheus-client', '~> 0.7.1'
|
30
30
|
s.add_development_dependency 'pry'
|
31
|
-
s.add_development_dependency 'rails', '>= 5.2'
|
31
|
+
s.add_development_dependency 'rails', '>= 5.2', '< 7'
|
32
32
|
s.add_development_dependency 'redis'
|
33
33
|
s.add_development_dependency 'rspec-rails', '>= 3.0.0'
|
34
34
|
s.add_development_dependency 'rubocop'
|
@@ -23,12 +23,12 @@ class DHC::Caching < DHC::Interceptor
|
|
23
23
|
def fetch(key)
|
24
24
|
central_response = @central[:read].fetch(key) if @central && @central[:read].present?
|
25
25
|
if central_response
|
26
|
-
|
26
|
+
DHC::Logger.info %([DHC] served from central cache: "#{key}")
|
27
27
|
return central_response
|
28
28
|
end
|
29
29
|
local_response = @local.fetch(key) if @local
|
30
30
|
if local_response
|
31
|
-
|
31
|
+
DHC::Logger.info %([DHC] served from local cache: "#{key}")
|
32
32
|
return local_response
|
33
33
|
end
|
34
34
|
end
|
@@ -6,80 +6,117 @@ class DHC::Throttle < DHC::Interceptor
|
|
6
6
|
class OutOfQuota < StandardError
|
7
7
|
end
|
8
8
|
|
9
|
+
CACHE_KEY = 'DHC/throttle/tracker/v1'
|
10
|
+
|
9
11
|
class << self
|
10
|
-
|
12
|
+
|
13
|
+
def tracker(provider)
|
14
|
+
(Rails.cache.read(CACHE_KEY) || {})[provider] || {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def tracker=(track)
|
18
|
+
Rails.cache.write(CACHE_KEY, (Rails.cache.read(CACHE_KEY) || {}).merge({ track[:provider] => track }))
|
19
|
+
end
|
11
20
|
end
|
12
21
|
|
13
22
|
def before_request
|
14
|
-
options = request.options.dig(:throttle)
|
15
23
|
return unless options
|
16
|
-
|
17
|
-
return unless break_options
|
18
|
-
break_when_quota_reached! if break_options.match('%')
|
24
|
+
break! if break?
|
19
25
|
end
|
20
26
|
|
21
27
|
def after_response
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
expires: expires(options: options[:expires], response: response)
|
28
|
+
return unless track?
|
29
|
+
self.class.tracker = {
|
30
|
+
provider: options.dig(:provider),
|
31
|
+
limit: limit,
|
32
|
+
remaining: remaining,
|
33
|
+
expires: expires
|
29
34
|
}
|
30
35
|
end
|
31
36
|
|
32
37
|
private
|
33
38
|
|
34
|
-
def
|
35
|
-
|
39
|
+
def options
|
40
|
+
@options ||= request.options.dig(:throttle) || {}
|
41
|
+
end
|
42
|
+
|
43
|
+
def provider
|
44
|
+
@provider ||= request.options.dig(:throttle, :provider)
|
45
|
+
end
|
46
|
+
|
47
|
+
def track?
|
48
|
+
(options.dig(:remaining) && [options.dig(:track), response.headers].none?(&:blank?) ||
|
49
|
+
options.dig(:track).present?
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
def break?
|
54
|
+
@do_break ||= begin
|
55
|
+
return if options.dig(:break) && !options.dig(:break).match('%')
|
56
|
+
tracker = self.class.tracker(options[:provider])
|
57
|
+
return if tracker.blank? || tracker[:remaining].blank? || tracker[:limit].blank? || tracker[:expires].blank?
|
58
|
+
return if Time.zone.now > tracker[:expires]
|
59
|
+
remaining = tracker[:remaining] * 100
|
60
|
+
limit = tracker[:limit]
|
61
|
+
remaining_quota = 100 - options[:break].to_i
|
62
|
+
remaining <= remaining_quota * limit
|
63
|
+
end
|
36
64
|
end
|
37
65
|
|
38
|
-
def
|
39
|
-
|
40
|
-
track = (self.class.track || {}).dig(options[:provider])
|
41
|
-
return if track.blank? || track[:remaining].blank? || track[:limit].blank? || track[:expires].blank?
|
42
|
-
return if Time.zone.now > track[:expires]
|
43
|
-
# avoid floats by multiplying with 100
|
44
|
-
remaining = track[:remaining] * 100
|
45
|
-
limit = track[:limit]
|
46
|
-
quota = 100 - options[:break].to_i
|
47
|
-
raise(OutOfQuota, "Reached predefined quota for #{options[:provider]}") if remaining < quota * limit
|
66
|
+
def break!
|
67
|
+
raise(OutOfQuota, "Reached predefined quota for #{provider}")
|
48
68
|
end
|
49
69
|
|
50
|
-
def limit
|
70
|
+
def limit
|
51
71
|
@limit ||=
|
52
|
-
if options.is_a?(Proc)
|
53
|
-
options.call(response)
|
54
|
-
elsif options.is_a?(Integer)
|
55
|
-
options
|
56
|
-
elsif options.is_a?(Hash) && options
|
57
|
-
response.headers[options
|
72
|
+
if options.dig(:limit).is_a?(Proc)
|
73
|
+
options.dig(:limit).call(response)
|
74
|
+
elsif options.dig(:limit).is_a?(Integer)
|
75
|
+
options.dig(:limit)
|
76
|
+
elsif options.dig(:limit).is_a?(Hash) && options.dig(:limit, :header) && response.headers
|
77
|
+
response.headers[options.dig(:limit, :header)]&.to_i
|
58
78
|
end
|
59
79
|
end
|
60
80
|
|
61
|
-
def remaining
|
62
|
-
@remaining ||=
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
81
|
+
def remaining
|
82
|
+
@remaining ||= begin
|
83
|
+
if options.dig(:remaining).is_a?(Proc)
|
84
|
+
options.dig(:remaining).call(response)
|
85
|
+
elsif options.dig(:remaining).is_a?(Hash) && options.dig(:remaining, :header) && response.headers
|
86
|
+
response.headers[options.dig(:remaining, :header)]&.to_i
|
87
|
+
elsif options.dig(:remaining).blank?
|
88
|
+
remaining_before = self.class.tracker(provider).dig(:remaining) || request.options.dig(:throttle, :limit)
|
89
|
+
expires = self.class.tracker(provider).dig(:expires)
|
90
|
+
if expires && expires > DateTime.now
|
91
|
+
remaining_before - 1
|
92
|
+
else
|
93
|
+
request.options.dig(:throttle, :limit) - 1
|
68
94
|
end
|
69
95
|
end
|
96
|
+
end
|
70
97
|
end
|
71
98
|
|
72
|
-
def expires
|
73
|
-
@expires ||=
|
74
|
-
|
99
|
+
def expires
|
100
|
+
@expires ||= begin
|
101
|
+
if options.dig(:expires).is_a?(ActiveSupport::Duration) && self.class.tracker(provider).dig(:expires).present?
|
102
|
+
if self.class.tracker(provider)[:expires] > DateTime.now
|
103
|
+
self.class.tracker(provider)[:expires]
|
104
|
+
else
|
105
|
+
DateTime.now + options.dig(:expires)
|
106
|
+
end
|
107
|
+
elsif options.dig(:expires).is_a?(Hash) && options.dig(:expires, :header)
|
75
108
|
|
76
|
-
|
77
|
-
|
109
|
+
convert_expire_value(response.headers[options.dig(:expires, :header)]) if response.headers
|
110
|
+
else
|
111
|
+
convert_expire_value(options.dig(:expires))
|
112
|
+
end
|
113
|
+
end
|
78
114
|
end
|
79
115
|
|
80
|
-
def
|
116
|
+
def convert_expire_value(value)
|
81
117
|
return if value.blank?
|
82
118
|
return value.call(response) if value.is_a?(Proc)
|
119
|
+
return DateTime.now + value if value.is_a?(ActiveSupport::Duration)
|
83
120
|
return Time.parse(value) if value.match(/GMT/)
|
84
121
|
Time.zone.at(value.to_i).to_datetime
|
85
122
|
end
|
data/lib/dhc/logger.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
require 'forwardable'
|
5
|
+
|
6
|
+
class DHC::Logger < Logger
|
7
|
+
include ActiveSupport::Configurable
|
8
|
+
include Singleton
|
9
|
+
|
10
|
+
config_accessor :logger
|
11
|
+
|
12
|
+
class << self
|
13
|
+
extend Forwardable
|
14
|
+
def_delegators :instance, :log, :info, :error, :warn, :debug
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(logdev = nil)
|
18
|
+
super
|
19
|
+
if DHC::Logger.logger
|
20
|
+
self.logger = DHC::Logger.logger
|
21
|
+
elsif defined? Rails
|
22
|
+
self.logger = Rails.logger
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.log(severity, message = nil, progname = nil)
|
27
|
+
return if logger.blank?
|
28
|
+
logger.log(severity, message, progname)
|
29
|
+
end
|
30
|
+
end
|
data/lib/dhc/rspec.rb
CHANGED
data/lib/dhc/version.rb
CHANGED
data/lib/dhc.rb
CHANGED
@@ -46,8 +46,8 @@ describe DHC::Caching do
|
|
46
46
|
it 'serves a response from local cache without trying the central cache' do
|
47
47
|
expect(Rails.cache).to receive(:fetch).at_least(:once).and_call_original
|
48
48
|
expect(Rails.cache).to receive(:write).and_call_original
|
49
|
-
expect(
|
50
|
-
|
49
|
+
expect(DHC::Logger).to receive(:info).with(%{[DHC] served from local cache: "DHC_CACHE(v1): GET http://depay.fi"}).and_call_original
|
50
|
+
response_has_been_cached_and_served_from_cache!
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
@@ -67,8 +67,8 @@ describe DHC::Caching do
|
|
67
67
|
expect(redis_cache).to receive(:write).and_return(true)
|
68
68
|
expect(Rails.cache).to receive(:fetch).and_call_original
|
69
69
|
expect(Rails.cache).to receive(:write).and_call_original
|
70
|
-
expect(
|
71
|
-
|
70
|
+
expect(DHC::Logger).to receive(:info).with(%{[DHC] served from central cache: "DHC_CACHE(v1): GET http://depay.fi"}).and_call_original
|
71
|
+
response_has_been_cached_and_served_from_cache!
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
@@ -78,8 +78,8 @@ describe DHC::Caching do
|
|
78
78
|
expect(redis_cache).to receive(:write).and_return(true)
|
79
79
|
expect(Rails.cache).to receive(:fetch).at_least(:once).and_call_original
|
80
80
|
expect(Rails.cache).to receive(:write).and_call_original
|
81
|
-
expect(
|
82
|
-
|
81
|
+
expect(DHC::Logger).to receive(:info).with(%{[DHC] served from local cache: "DHC_CACHE(v1): GET http://depay.fi"}).and_call_original
|
82
|
+
response_has_been_cached_and_served_from_cache!
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
@@ -97,8 +97,8 @@ describe DHC::Caching do
|
|
97
97
|
expect(redis_cache).not_to receive(:write)
|
98
98
|
expect(Rails.cache).to receive(:fetch).and_call_original
|
99
99
|
expect(Rails.cache).to receive(:write).and_call_original
|
100
|
-
expect(
|
101
|
-
|
100
|
+
expect(DHC::Logger).to receive(:info).with(%{[DHC] served from central cache: "DHC_CACHE(v1): GET http://depay.fi"}).and_call_original
|
101
|
+
response_has_been_cached_and_served_from_cache!
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
@@ -115,8 +115,8 @@ describe DHC::Caching do
|
|
115
115
|
expect(redis_cache).to receive(:write).and_return(true)
|
116
116
|
expect(Rails.cache).to receive(:fetch).at_least(:once).and_call_original
|
117
117
|
expect(Rails.cache).to receive(:write).and_call_original
|
118
|
-
expect(
|
119
|
-
|
118
|
+
expect(DHC::Logger).to receive(:info).with(%{[DHC] served from local cache: "DHC_CACHE(v1): GET http://depay.fi"}).and_call_original
|
119
|
+
response_has_been_cached_and_served_from_cache!
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
@@ -132,8 +132,8 @@ describe DHC::Caching do
|
|
132
132
|
it 'does not inquire the local cache for information neither to write them' do
|
133
133
|
expect(redis_cache).to receive(:fetch).and_return(nil, body: '<h1>Hi there</h1>', code: 200, headers: nil, return_code: nil, mock: :webmock)
|
134
134
|
expect(redis_cache).to receive(:write).and_return(true)
|
135
|
-
expect(
|
136
|
-
|
135
|
+
expect(DHC::Logger).to receive(:info).with(%{[DHC] served from central cache: "DHC_CACHE(v1): GET http://depay.fi"}).and_call_original
|
136
|
+
response_has_been_cached_and_served_from_cache!
|
137
137
|
end
|
138
138
|
end
|
139
139
|
end
|
@@ -25,8 +25,8 @@ describe DHC::Throttle do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
before(:each) do
|
28
|
-
DHC::Throttle.track = nil
|
29
28
|
DHC.config.interceptors = [DHC::Throttle]
|
29
|
+
Rails.cache.write(DHC::Throttle::CACHE_KEY, nil)
|
30
30
|
|
31
31
|
stub_request(:get, 'http://depay.fi').to_return(
|
32
32
|
headers: { 'limit' => quota_limit, 'remaining' => quota_remaining, 'reset' => quota_reset }
|
@@ -35,8 +35,8 @@ describe DHC::Throttle do
|
|
35
35
|
|
36
36
|
it 'tracks the request limits based on response data' do
|
37
37
|
DHC.get('http://depay.fi', options)
|
38
|
-
expect(DHC
|
39
|
-
expect(DHC
|
38
|
+
expect(Rails.cache.read('DHC/throttle/tracker/v1')[provider][:limit]).to eq quota_limit
|
39
|
+
expect(Rails.cache.read('DHC/throttle/tracker/v1')[provider][:remaining]).to eq quota_remaining
|
40
40
|
end
|
41
41
|
|
42
42
|
context 'fix predefined integer for limit' do
|
@@ -44,7 +44,7 @@ describe DHC::Throttle do
|
|
44
44
|
|
45
45
|
it 'tracks the limit based on initialy provided data' do
|
46
46
|
DHC.get('http://depay.fi', options)
|
47
|
-
expect(DHC
|
47
|
+
expect(Rails.cache.read('DHC/throttle/tracker/v1')[provider][:limit]).to eq options_limit
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
describe DHC::Throttle do
|
6
|
+
let(:options) do
|
7
|
+
{
|
8
|
+
throttle: {
|
9
|
+
provider: provider,
|
10
|
+
track: true,
|
11
|
+
limit: quota_limit,
|
12
|
+
expires: 1.minute,
|
13
|
+
break: break_after
|
14
|
+
}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:provider) { 'depay.fi' }
|
19
|
+
let(:quota_limit) { 100 }
|
20
|
+
let(:break_after) { '80%' }
|
21
|
+
|
22
|
+
before(:each) do
|
23
|
+
DHC.config.interceptors = [DHC::Throttle]
|
24
|
+
Rails.cache.write(DHC::Throttle::CACHE_KEY, nil)
|
25
|
+
|
26
|
+
stub_request(:get, 'http://depay.fi').to_return(status: 200)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'tracks the request limits based on response data' do
|
30
|
+
DHC.get('http://depay.fi', options)
|
31
|
+
expect(Rails.cache.read('DHC/throttle/tracker/v1')[provider][:limit]).to eq 100
|
32
|
+
expect(Rails.cache.read('DHC/throttle/tracker/v1')[provider][:remaining]).to eq quota_limit - 1
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'breaks' do
|
36
|
+
let(:quota_limit) { 100 }
|
37
|
+
let(:break_after) { '79%' }
|
38
|
+
|
39
|
+
it 'hit the breaks if throttling quota is reached' do
|
40
|
+
79.times do
|
41
|
+
DHC.get('http://depay.fi', options)
|
42
|
+
end
|
43
|
+
expect { DHC.get('http://depay.fi', options) }.to raise_error(
|
44
|
+
DHC::Throttle::OutOfQuota,
|
45
|
+
'Reached predefined quota for depay.fi'
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'still within quota' do
|
50
|
+
let(:break_after) { '80%' }
|
51
|
+
|
52
|
+
it 'does not hit the breaks' do
|
53
|
+
80.times do
|
54
|
+
DHC.get('http://depay.fi', options)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'does hit the breaks surpassing quota' do
|
59
|
+
80.times do
|
60
|
+
DHC.get('http://depay.fi', options)
|
61
|
+
end
|
62
|
+
expect { DHC.get('http://depay.fi', options) }.to raise_error(
|
63
|
+
DHC::Throttle::OutOfQuota,
|
64
|
+
'Reached predefined quota for depay.fi'
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'expires' do
|
71
|
+
let(:break_after) { '80%' }
|
72
|
+
let(:quota_limit) { 100 }
|
73
|
+
|
74
|
+
it 'attempts another request if the quota expired' do
|
75
|
+
80.times do
|
76
|
+
DHC.get('http://depay.fi', options)
|
77
|
+
end
|
78
|
+
expect { DHC.get('http://depay.fi', options) }.to raise_error(
|
79
|
+
DHC::Throttle::OutOfQuota,
|
80
|
+
'Reached predefined quota for depay.fi'
|
81
|
+
)
|
82
|
+
Timecop.travel(Time.zone.now + 1.minute)
|
83
|
+
80.times do
|
84
|
+
DHC.get('http://depay.fi', options)
|
85
|
+
end
|
86
|
+
expect { DHC.get('http://depay.fi', options) }.to raise_error(
|
87
|
+
DHC::Throttle::OutOfQuota,
|
88
|
+
'Reached predefined quota for depay.fi'
|
89
|
+
)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'multiple provider' do
|
94
|
+
it 'tracks multiple providers without a problem' do
|
95
|
+
DHC.get('http://depay.fi', options)
|
96
|
+
stub_request(:get, 'http://depay.app').to_return(status: 200)
|
97
|
+
DHC.get('http://depay.app', {
|
98
|
+
throttle: {
|
99
|
+
provider: 'depay.app',
|
100
|
+
track: true,
|
101
|
+
limit: quota_limit,
|
102
|
+
expires: 1.minute,
|
103
|
+
break: break_after
|
104
|
+
}
|
105
|
+
})
|
106
|
+
expect(Rails.cache.read('DHC/throttle/tracker/v1')['depay.fi']).to be_present
|
107
|
+
expect(Rails.cache.read('DHC/throttle/tracker/v1')['depay.app']).to be_present
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dhc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- https://github.com/DePayFi/dhc/contributors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -87,6 +87,9 @@ dependencies:
|
|
87
87
|
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '5.2'
|
90
|
+
- - "<"
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '7'
|
90
93
|
type: :development
|
91
94
|
prerelease: false
|
92
95
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -94,6 +97,9 @@ dependencies:
|
|
94
97
|
- - ">="
|
95
98
|
- !ruby/object:Gem::Version
|
96
99
|
version: '5.2'
|
100
|
+
- - "<"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '7'
|
97
103
|
- !ruby/object:Gem::Dependency
|
98
104
|
name: redis
|
99
105
|
requirement: !ruby/object:Gem::Requirement
|
@@ -231,6 +237,7 @@ files:
|
|
231
237
|
- lib/dhc/interceptors/rollbar.rb
|
232
238
|
- lib/dhc/interceptors/throttle.rb
|
233
239
|
- lib/dhc/interceptors/zipkin.rb
|
240
|
+
- lib/dhc/logger.rb
|
234
241
|
- lib/dhc/railtie.rb
|
235
242
|
- lib/dhc/request.rb
|
236
243
|
- lib/dhc/response.rb
|
@@ -338,6 +345,7 @@ files:
|
|
338
345
|
- spec/interceptors/rollbar/invalid_encoding_spec.rb
|
339
346
|
- spec/interceptors/rollbar/main_spec.rb
|
340
347
|
- spec/interceptors/throttle/main_spec.rb
|
348
|
+
- spec/interceptors/throttle/manually_spec.rb
|
341
349
|
- spec/interceptors/throttle/reset_track_spec.rb
|
342
350
|
- spec/interceptors/zipkin/distributed_tracing_spec.rb
|
343
351
|
- spec/rails_helper.rb
|
@@ -492,6 +500,7 @@ test_files:
|
|
492
500
|
- spec/interceptors/rollbar/invalid_encoding_spec.rb
|
493
501
|
- spec/interceptors/rollbar/main_spec.rb
|
494
502
|
- spec/interceptors/throttle/main_spec.rb
|
503
|
+
- spec/interceptors/throttle/manually_spec.rb
|
495
504
|
- spec/interceptors/throttle/reset_track_spec.rb
|
496
505
|
- spec/interceptors/zipkin/distributed_tracing_spec.rb
|
497
506
|
- spec/rails_helper.rb
|