freno-client 0.8.1 → 0.8.2
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/.github/workflows/ruby.yml +35 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +31 -166
- data/Gemfile +5 -1
- data/README.md +2 -4
- data/Rakefile +2 -0
- data/freno-client.gemspec +7 -3
- data/gemfiles/faraday_0.gemfile +22 -0
- data/gemfiles/faraday_1.gemfile +22 -0
- data/gemfiles/faraday_2.gemfile +22 -0
- data/lib/freno/client/errors.rb +2 -0
- data/lib/freno/client/preconditions.rb +4 -2
- data/lib/freno/client/request.rb +9 -8
- data/lib/freno/client/requests/check.rb +2 -1
- data/lib/freno/client/requests/check_read.rb +2 -1
- data/lib/freno/client/requests/replication_delay.rb +2 -1
- data/lib/freno/client/result.rb +3 -1
- data/lib/freno/client/version.rb +3 -1
- data/lib/freno/client.rb +57 -18
- data/lib/freno/throttler/circuit_breaker.rb +2 -2
- data/lib/freno/throttler/errors.rb +2 -1
- data/lib/freno/throttler/instrumenter.rb +3 -3
- data/lib/freno/throttler/mapper.rb +2 -2
- data/lib/freno/throttler.rb +31 -22
- metadata +14 -10
- data/.travis.yml +0 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 808823b23d76b3a540d9d17d2c6e28b428fd3cb387c941f79c749779393ac462
|
|
4
|
+
data.tar.gz: cf58a8db9c3d7fa2bea92727b3336a62fded79081723ee5e13555a72e6d68c62
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1fb13835bd9d2c9dd64c8bc3ae6e9931e0bd16a82cfa0ffbc4ed276505e453d4cf8a371cd66e6a0da19c2755e1174ce2812c55d0b12ce781b7a52f08add3f838
|
|
7
|
+
data.tar.gz: 540f2de04000141a1c636ab169e178a99a48dc19fe53557f7afba59dd2ddd2e2c407178e8a4f5e2daeb82b54871eac21f7d369854f1e9d7b87bbde1226289ffc
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Ruby
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches:
|
|
5
|
+
- main
|
|
6
|
+
pull_request:
|
|
7
|
+
branches:
|
|
8
|
+
- main
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
jobs:
|
|
12
|
+
test:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
strategy:
|
|
15
|
+
matrix:
|
|
16
|
+
ruby-version:
|
|
17
|
+
- '2.7'
|
|
18
|
+
- '3.0'
|
|
19
|
+
- '3.1'
|
|
20
|
+
gemfile-path:
|
|
21
|
+
- Gemfile
|
|
22
|
+
- gemfiles/faraday_0.gemfile
|
|
23
|
+
- gemfiles/faraday_1.gemfile
|
|
24
|
+
- gemfiles/faraday_2.gemfile
|
|
25
|
+
env:
|
|
26
|
+
BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile-path }}
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v3
|
|
29
|
+
- name: Set up Ruby
|
|
30
|
+
uses: ruby/setup-ruby@v1
|
|
31
|
+
with:
|
|
32
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
33
|
+
bundler-cache: true
|
|
34
|
+
- name: Run tests
|
|
35
|
+
run: bundle exec rake
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -1,179 +1,44 @@
|
|
|
1
|
-
require:
|
|
1
|
+
require:
|
|
2
|
+
- rubocop-minitest
|
|
3
|
+
- rubocop-performance
|
|
4
|
+
- rubocop-rake
|
|
2
5
|
|
|
3
6
|
AllCops:
|
|
4
|
-
|
|
5
|
-
TargetRubyVersion: 2.
|
|
7
|
+
NewCops: enable
|
|
8
|
+
TargetRubyVersion: 2.7
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
Enabled: true
|
|
9
|
-
Bundler/OrderedGems:
|
|
10
|
-
Enabled: true
|
|
11
|
-
|
|
12
|
-
Layout/BlockAlignment:
|
|
13
|
-
Enabled: true
|
|
14
|
-
Layout/BlockEndNewline:
|
|
15
|
-
Enabled: true
|
|
16
|
-
Layout/ConditionPosition:
|
|
17
|
-
Enabled: true
|
|
18
|
-
Layout/DefEndAlignment:
|
|
19
|
-
Enabled: true
|
|
20
|
-
Layout/EndOfLine:
|
|
21
|
-
Enabled: true
|
|
22
|
-
Layout/IndentationStyle:
|
|
23
|
-
Enabled: true
|
|
24
|
-
Layout/InitialIndentation:
|
|
25
|
-
Enabled: true
|
|
26
|
-
Layout/SpaceAfterColon:
|
|
27
|
-
Enabled: true
|
|
28
|
-
Layout/SpaceAfterComma:
|
|
29
|
-
Enabled: true
|
|
30
|
-
Layout/SpaceAfterMethodName:
|
|
31
|
-
Enabled: true
|
|
32
|
-
Layout/SpaceAfterNot:
|
|
33
|
-
Enabled: true
|
|
34
|
-
Layout/SpaceAfterSemicolon:
|
|
35
|
-
Enabled: true
|
|
36
|
-
Layout/SpaceAroundBlockParameters:
|
|
37
|
-
Enabled: true
|
|
38
|
-
Layout/SpaceAroundEqualsInParameterDefault:
|
|
39
|
-
Enabled: true
|
|
40
|
-
Layout/SpaceInsideArrayPercentLiteral:
|
|
41
|
-
Enabled: true
|
|
42
|
-
Layout/SpaceInsideParens:
|
|
43
|
-
Enabled: true
|
|
44
|
-
Layout/SpaceInsideRangeLiteral:
|
|
45
|
-
Enabled: true
|
|
46
|
-
Layout/TrailingEmptyLines:
|
|
47
|
-
Enabled: true
|
|
48
|
-
Layout/TrailingWhitespace:
|
|
49
|
-
Enabled: true
|
|
50
|
-
|
|
51
|
-
Lint/CircularArgumentReference:
|
|
52
|
-
Enabled: true
|
|
53
|
-
Lint/Debugger:
|
|
54
|
-
Enabled: true
|
|
55
|
-
Lint/DeprecatedClassMethods:
|
|
56
|
-
Enabled: true
|
|
57
|
-
Lint/DuplicateHashKey:
|
|
58
|
-
Enabled: true
|
|
59
|
-
Lint/DuplicateMethods:
|
|
60
|
-
Enabled: true
|
|
61
|
-
Lint/EachWithObjectArgument:
|
|
62
|
-
Enabled: true
|
|
63
|
-
Lint/ElseLayout:
|
|
64
|
-
Enabled: true
|
|
65
|
-
Lint/EmptyEnsure:
|
|
66
|
-
Enabled: true
|
|
67
|
-
Lint/EmptyInterpolation:
|
|
68
|
-
Enabled: true
|
|
69
|
-
Lint/EnsureReturn:
|
|
70
|
-
Enabled: true
|
|
71
|
-
Lint/FlipFlop:
|
|
72
|
-
Enabled: true
|
|
73
|
-
Lint/FloatOutOfRange:
|
|
74
|
-
Enabled: true
|
|
75
|
-
Lint/FormatParameterMismatch:
|
|
76
|
-
Enabled: true
|
|
77
|
-
Lint/LiteralInInterpolation:
|
|
78
|
-
Enabled: true
|
|
79
|
-
Lint/Loop:
|
|
80
|
-
Enabled: true
|
|
81
|
-
Lint/NextWithoutAccumulator:
|
|
82
|
-
Enabled: true
|
|
83
|
-
Lint/RandOne:
|
|
84
|
-
Enabled: true
|
|
85
|
-
Lint/RedundantSplatExpansion:
|
|
86
|
-
Enabled: true
|
|
87
|
-
Lint/RedundantStringCoercion:
|
|
88
|
-
Enabled: true
|
|
89
|
-
Lint/RequireParentheses:
|
|
90
|
-
Enabled: true
|
|
91
|
-
Lint/RescueException:
|
|
92
|
-
Enabled: true
|
|
93
|
-
Lint/UnderscorePrefixedVariableName:
|
|
94
|
-
Enabled: true
|
|
95
|
-
Lint/UnreachableCode:
|
|
96
|
-
Enabled: true
|
|
97
|
-
Lint/UselessComparison:
|
|
98
|
-
Enabled: true
|
|
99
|
-
Lint/UselessSetterCall:
|
|
100
|
-
Enabled: true
|
|
101
|
-
Lint/Void:
|
|
10
|
+
Layout/MultilineMethodCallIndentation:
|
|
102
11
|
Enabled: true
|
|
12
|
+
EnforcedStyle: indented_relative_to_receiver
|
|
103
13
|
|
|
104
|
-
|
|
105
|
-
Enabled:
|
|
106
|
-
Naming/ClassAndModuleCamelCase:
|
|
107
|
-
Enabled: true
|
|
108
|
-
Naming/FileName:
|
|
109
|
-
Enabled: true
|
|
110
|
-
Naming/MethodName:
|
|
111
|
-
Enabled: true
|
|
14
|
+
Metrics:
|
|
15
|
+
Enabled: false
|
|
112
16
|
|
|
113
|
-
|
|
114
|
-
Enabled:
|
|
115
|
-
|
|
116
|
-
Enabled:
|
|
117
|
-
|
|
118
|
-
Enabled:
|
|
119
|
-
|
|
120
|
-
Enabled:
|
|
121
|
-
|
|
122
|
-
Enabled:
|
|
123
|
-
Performance/RedundantMerge:
|
|
124
|
-
Enabled: true
|
|
125
|
-
MaxKeyValuePairs: 1
|
|
126
|
-
Performance/ReverseEach:
|
|
127
|
-
Enabled: true
|
|
128
|
-
Performance/Size:
|
|
129
|
-
Enabled: true
|
|
130
|
-
Performance/StartWith:
|
|
131
|
-
Enabled: true
|
|
17
|
+
Minitest/AssertEmptyLiteral:
|
|
18
|
+
Enabled: false
|
|
19
|
+
Minitest/AssertEqual:
|
|
20
|
+
Enabled: false
|
|
21
|
+
Minitest/AssertPredicate:
|
|
22
|
+
Enabled: false
|
|
23
|
+
Minitest/MultipleAssertions:
|
|
24
|
+
Enabled: false
|
|
25
|
+
Minitest/RefutePredicate:
|
|
26
|
+
Enabled: false
|
|
132
27
|
|
|
133
|
-
|
|
28
|
+
Naming/RescuedExceptionsVariableName:
|
|
134
29
|
Enabled: true
|
|
30
|
+
PreferredName: error
|
|
135
31
|
|
|
136
|
-
Style/
|
|
137
|
-
Enabled: true
|
|
138
|
-
Style/BeginBlock:
|
|
139
|
-
Enabled: true
|
|
140
|
-
Style/BlockComments:
|
|
141
|
-
Enabled: true
|
|
142
|
-
Style/CaseEquality:
|
|
143
|
-
Enabled: true
|
|
144
|
-
Style/CharacterLiteral:
|
|
145
|
-
Enabled: true
|
|
146
|
-
Style/ClassMethods:
|
|
147
|
-
Enabled: true
|
|
148
|
-
Style/DefWithParentheses:
|
|
149
|
-
Enabled: true
|
|
150
|
-
Style/EndBlock:
|
|
151
|
-
Enabled: true
|
|
152
|
-
Style/For:
|
|
153
|
-
Enabled: true
|
|
154
|
-
Style/HashSyntax:
|
|
155
|
-
Enabled: true
|
|
156
|
-
EnforcedStyle: ruby19
|
|
157
|
-
Style/LambdaCall:
|
|
158
|
-
Enabled: true
|
|
159
|
-
Style/MethodCallWithoutArgsParentheses:
|
|
160
|
-
Enabled: true
|
|
161
|
-
Style/MethodDefParentheses:
|
|
162
|
-
Enabled: true
|
|
163
|
-
Style/MultilineIfThen:
|
|
164
|
-
Enabled: true
|
|
165
|
-
Style/NilComparison:
|
|
166
|
-
Enabled: true
|
|
167
|
-
Style/Not:
|
|
168
|
-
Enabled: true
|
|
169
|
-
Style/OneLineConditional:
|
|
170
|
-
Enabled: true
|
|
171
|
-
Style/RedundantSortBy:
|
|
172
|
-
Enabled: true
|
|
173
|
-
Style/Sample:
|
|
174
|
-
Enabled: true
|
|
175
|
-
Style/StabbyLambdaParentheses:
|
|
32
|
+
Style/ClassAndModuleChildren:
|
|
176
33
|
Enabled: true
|
|
34
|
+
Exclude:
|
|
35
|
+
- test/**/*
|
|
36
|
+
Style/Documentation:
|
|
37
|
+
Enabled: false
|
|
38
|
+
Style/IfUnlessModifier:
|
|
39
|
+
Enabled: false
|
|
177
40
|
Style/StringLiterals:
|
|
178
41
|
Enabled: true
|
|
179
42
|
EnforcedStyle: double_quotes
|
|
43
|
+
Style/SymbolArray:
|
|
44
|
+
Enabled: false
|
data/Gemfile
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
source "https://rubygems.org"
|
|
2
4
|
|
|
3
5
|
gemspec
|
|
@@ -9,6 +11,8 @@ end
|
|
|
9
11
|
group :test do
|
|
10
12
|
gem "minitest", ">= 5"
|
|
11
13
|
gem "mocha"
|
|
12
|
-
gem "rubocop", "~>
|
|
14
|
+
gem "rubocop", "~> 1.37", require: false
|
|
15
|
+
gem "rubocop-minitest", require: false
|
|
13
16
|
gem "rubocop-performance", require: false
|
|
17
|
+
gem "rubocop-rake", require: false
|
|
14
18
|
end
|
data/README.md
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
A ruby client and throttling library for [Freno](https://github.com/github/freno): the cooperative, highly available throttler service.
|
|
1
|
+
A Ruby client and throttling library for [Freno](https://github.com/github/freno): the cooperative, highly available throttler service.
|
|
4
2
|
|
|
5
3
|
## Current status
|
|
6
4
|
|
|
@@ -177,7 +175,7 @@ end
|
|
|
177
175
|
|
|
178
176
|
### Throttler objects
|
|
179
177
|
|
|
180
|
-
Apart from the operations above, freno-client comes with `Freno::Throttler`, a
|
|
178
|
+
Apart from the operations above, freno-client comes with `Freno::Throttler`, a Ruby library for throttling. You can use it in the following way:
|
|
181
179
|
|
|
182
180
|
```ruby
|
|
183
181
|
require "freno/throttler"
|
data/Rakefile
CHANGED
data/freno-client.gemspec
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative "lib/freno/client/version"
|
|
2
4
|
|
|
3
5
|
Gem::Specification.new do |spec|
|
|
@@ -11,14 +13,16 @@ Gem::Specification.new do |spec|
|
|
|
11
13
|
freno-client is a Ruby library that interacts with Freno using HTTP.
|
|
12
14
|
Freno is a throttling service and its source code is available at
|
|
13
15
|
https://github.com/github/freno
|
|
14
|
-
|
|
16
|
+
DESC
|
|
15
17
|
|
|
16
18
|
spec.homepage = "https://github.com/github/freno-client"
|
|
17
19
|
spec.license = "MIT"
|
|
18
20
|
|
|
19
|
-
spec.required_ruby_version = ">= 2.
|
|
21
|
+
spec.required_ruby_version = ">= 2.7.0"
|
|
20
22
|
|
|
21
23
|
spec.files = `git ls-files -z`.split("\x0").grep_v(/^(bin|test)/)
|
|
22
24
|
|
|
23
|
-
spec.add_dependency "faraday", "
|
|
25
|
+
spec.add_dependency "faraday", "< 3"
|
|
26
|
+
|
|
27
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
|
24
28
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gemspec path: ".."
|
|
6
|
+
|
|
7
|
+
gem "faraday", "~> 0.0"
|
|
8
|
+
|
|
9
|
+
# Content below copied from Gemfile
|
|
10
|
+
|
|
11
|
+
group :development do
|
|
12
|
+
gem "rake"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
group :test do
|
|
16
|
+
gem "minitest", ">= 5"
|
|
17
|
+
gem "mocha"
|
|
18
|
+
gem "rubocop", "~> 1.37", require: false
|
|
19
|
+
gem "rubocop-minitest", require: false
|
|
20
|
+
gem "rubocop-performance", require: false
|
|
21
|
+
gem "rubocop-rake", require: false
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gemspec path: ".."
|
|
6
|
+
|
|
7
|
+
gem "faraday", "~> 1.0"
|
|
8
|
+
|
|
9
|
+
# Content below copied from Gemfile
|
|
10
|
+
|
|
11
|
+
group :development do
|
|
12
|
+
gem "rake"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
group :test do
|
|
16
|
+
gem "minitest", ">= 5"
|
|
17
|
+
gem "mocha"
|
|
18
|
+
gem "rubocop", "~> 1.37", require: false
|
|
19
|
+
gem "rubocop-minitest", require: false
|
|
20
|
+
gem "rubocop-performance", require: false
|
|
21
|
+
gem "rubocop-rake", require: false
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gemspec path: ".."
|
|
6
|
+
|
|
7
|
+
gem "faraday", "~> 2.0"
|
|
8
|
+
|
|
9
|
+
# Content below copied from Gemfile
|
|
10
|
+
|
|
11
|
+
group :development do
|
|
12
|
+
gem "rake"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
group :test do
|
|
16
|
+
gem "minitest", ">= 5"
|
|
17
|
+
gem "mocha"
|
|
18
|
+
gem "rubocop", "~> 1.37", require: false
|
|
19
|
+
gem "rubocop-minitest", require: false
|
|
20
|
+
gem "rubocop-performance", require: false
|
|
21
|
+
gem "rubocop-rake", require: false
|
|
22
|
+
end
|
data/lib/freno/client/errors.rb
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Freno
|
|
2
4
|
class Client
|
|
3
5
|
module Preconditions
|
|
4
|
-
|
|
6
|
+
module_function
|
|
5
7
|
|
|
6
8
|
PreconditionNotMet = Class.new(ArgumentError)
|
|
7
9
|
|
|
@@ -21,7 +23,7 @@ module Freno
|
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def report
|
|
24
|
-
raise PreconditionNotMet
|
|
26
|
+
raise PreconditionNotMet, errors.join("\n") unless errors.empty?
|
|
25
27
|
end
|
|
26
28
|
end
|
|
27
29
|
|
data/lib/freno/client/request.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative "preconditions"
|
|
2
4
|
require_relative "result"
|
|
3
5
|
require_relative "errors"
|
|
@@ -5,11 +7,9 @@ require_relative "errors"
|
|
|
5
7
|
module Freno
|
|
6
8
|
class Client
|
|
7
9
|
class Request
|
|
8
|
-
|
|
9
10
|
include Freno::Client::Preconditions
|
|
10
11
|
|
|
11
|
-
attr_reader :faraday, :args, :options
|
|
12
|
-
attr_reader :raise_on_timeout
|
|
12
|
+
attr_reader :faraday, :args, :options, :raise_on_timeout
|
|
13
13
|
|
|
14
14
|
def self.perform(**kwargs)
|
|
15
15
|
new(**kwargs).perform
|
|
@@ -18,7 +18,7 @@ module Freno
|
|
|
18
18
|
def initialize(**kwargs)
|
|
19
19
|
@args = kwargs
|
|
20
20
|
@faraday = kwargs.delete(:faraday) || nil
|
|
21
|
-
@options = kwargs.delete(:options) ||
|
|
21
|
+
@options = kwargs.delete(:options) || {}
|
|
22
22
|
|
|
23
23
|
@raise_on_timeout = options.fetch(:raise_on_timeout, true)
|
|
24
24
|
@verb = options.fetch(:verb, :head)
|
|
@@ -27,11 +27,12 @@ module Freno
|
|
|
27
27
|
def perform
|
|
28
28
|
response = request(verb, path, params)
|
|
29
29
|
process_response(response)
|
|
30
|
-
rescue Faraday::TimeoutError =>
|
|
31
|
-
raise Freno::Error
|
|
30
|
+
rescue Faraday::TimeoutError => error
|
|
31
|
+
raise Freno::Error, error if raise_on_timeout
|
|
32
|
+
|
|
32
33
|
Result.from_meaning(:request_timeout)
|
|
33
|
-
rescue =>
|
|
34
|
-
raise Freno::Error
|
|
34
|
+
rescue StandardError => error
|
|
35
|
+
raise Freno::Error, error
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
protected
|
data/lib/freno/client/result.rb
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "json"
|
|
2
4
|
|
|
3
5
|
module Freno
|
|
4
6
|
class Client
|
|
5
7
|
class Result
|
|
6
|
-
|
|
7
8
|
# https://github.com/github/freno/blob/master/doc/http.md#status-codes
|
|
8
9
|
FRENO_STATUS_CODE_MEANINGS = {
|
|
9
10
|
200 => :ok,
|
|
@@ -55,6 +56,7 @@ module Freno
|
|
|
55
56
|
|
|
56
57
|
def ==(other)
|
|
57
58
|
return meaning == other if other.is_a? Symbol
|
|
59
|
+
|
|
58
60
|
code == other
|
|
59
61
|
end
|
|
60
62
|
end
|
data/lib/freno/client/version.rb
CHANGED
data/lib/freno/client.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "freno/client/version"
|
|
2
4
|
require "freno/client/requests/check_read"
|
|
3
5
|
require "freno/client/requests/check"
|
|
@@ -8,10 +10,10 @@ module Freno
|
|
|
8
10
|
class DecorationError < ArgumentError; end
|
|
9
11
|
|
|
10
12
|
REQUESTS = {
|
|
11
|
-
check:
|
|
12
|
-
check_read:
|
|
13
|
-
replication_delay: Requests::ReplicationDelay
|
|
14
|
-
}
|
|
13
|
+
check: Requests::Check,
|
|
14
|
+
check_read: Requests::CheckRead,
|
|
15
|
+
replication_delay: Requests::ReplicationDelay
|
|
16
|
+
}.freeze
|
|
15
17
|
|
|
16
18
|
attr_reader :faraday, :decorators, :decorated_requests
|
|
17
19
|
attr_accessor :default_app, :default_store_name, :default_store_type, :options
|
|
@@ -78,8 +80,21 @@ module Freno
|
|
|
78
80
|
#
|
|
79
81
|
# Returns Result
|
|
80
82
|
#
|
|
81
|
-
def check_read(
|
|
82
|
-
|
|
83
|
+
def check_read(
|
|
84
|
+
threshold:,
|
|
85
|
+
app: default_app,
|
|
86
|
+
store_type: default_store_type,
|
|
87
|
+
store_name: default_store_name,
|
|
88
|
+
options: {}
|
|
89
|
+
)
|
|
90
|
+
perform(
|
|
91
|
+
:check_read,
|
|
92
|
+
threshold: threshold,
|
|
93
|
+
app: app,
|
|
94
|
+
store_type: store_type,
|
|
95
|
+
store_name: store_name,
|
|
96
|
+
options: self.options.merge(options)
|
|
97
|
+
)
|
|
83
98
|
end
|
|
84
99
|
|
|
85
100
|
# Implements a specific check request to retrieve the consolidated replication
|
|
@@ -89,11 +104,21 @@ module Freno
|
|
|
89
104
|
#
|
|
90
105
|
# Returns Float indicating the replication delay in seconds as reported by Freno.
|
|
91
106
|
#
|
|
92
|
-
def replication_delay(
|
|
93
|
-
|
|
107
|
+
def replication_delay(
|
|
108
|
+
app: default_app,
|
|
109
|
+
store_type: default_store_type,
|
|
110
|
+
store_name: default_store_name,
|
|
111
|
+
options: {}
|
|
112
|
+
)
|
|
113
|
+
perform(
|
|
114
|
+
:replication_delay,
|
|
115
|
+
app: app,
|
|
116
|
+
store_type: store_type,
|
|
117
|
+
store_name: store_name,
|
|
118
|
+
options: self.options.merge(options)
|
|
119
|
+
)
|
|
94
120
|
end
|
|
95
121
|
|
|
96
|
-
|
|
97
122
|
# Determines whether Freno considers it"s OK to write to masters
|
|
98
123
|
#
|
|
99
124
|
# Returns true or false.
|
|
@@ -107,8 +132,20 @@ module Freno
|
|
|
107
132
|
#
|
|
108
133
|
# Returns true or false.
|
|
109
134
|
#
|
|
110
|
-
def check_read?(
|
|
111
|
-
|
|
135
|
+
def check_read?(
|
|
136
|
+
threshold:,
|
|
137
|
+
app: default_app,
|
|
138
|
+
store_type: default_store_type,
|
|
139
|
+
store_name: default_store_name,
|
|
140
|
+
options: {}
|
|
141
|
+
)
|
|
142
|
+
check_read(
|
|
143
|
+
threshold: threshold,
|
|
144
|
+
app: app,
|
|
145
|
+
store_type: store_type,
|
|
146
|
+
store_name: store_name,
|
|
147
|
+
options: self.options.merge(options)
|
|
148
|
+
).ok?
|
|
112
149
|
end
|
|
113
150
|
|
|
114
151
|
# Configures the client to extend the functionality of part or all the API
|
|
@@ -165,12 +202,13 @@ module Freno
|
|
|
165
202
|
# end
|
|
166
203
|
# ```
|
|
167
204
|
#
|
|
168
|
-
def decorate(
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
205
|
+
def decorate(request_or_all, with:)
|
|
206
|
+
requests =
|
|
207
|
+
if request_or_all == :all
|
|
208
|
+
REQUESTS.keys
|
|
209
|
+
else
|
|
210
|
+
Array(request_or_all)
|
|
211
|
+
end
|
|
174
212
|
|
|
175
213
|
with = Array(with)
|
|
176
214
|
validate!(with)
|
|
@@ -195,7 +233,7 @@ module Freno
|
|
|
195
233
|
outermost = to_decorate[0]
|
|
196
234
|
current = outermost
|
|
197
235
|
|
|
198
|
-
(to_decorate[1
|
|
236
|
+
(to_decorate[1..]).each do |decorator|
|
|
199
237
|
current.request = decorator
|
|
200
238
|
current = current.request
|
|
201
239
|
end
|
|
@@ -207,6 +245,7 @@ module Freno
|
|
|
207
245
|
def validate!(decorators)
|
|
208
246
|
decorators.each do |decorator|
|
|
209
247
|
raise DecorationError, "Cannot reuse decorator instance: #{decorator}" if already_registered?(decorator)
|
|
248
|
+
|
|
210
249
|
registered_decorators << decorator
|
|
211
250
|
end
|
|
212
251
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Freno
|
|
2
4
|
class Throttler
|
|
3
|
-
|
|
4
5
|
# A CircuitBreaker is the entry point of the pattern with same name.
|
|
5
6
|
# (see https://martinfowler.com/bliki/CircuitBreaker.html)
|
|
6
7
|
#
|
|
@@ -14,7 +15,6 @@ module Freno
|
|
|
14
15
|
# next request is allowed.
|
|
15
16
|
#
|
|
16
17
|
module CircuitBreaker
|
|
17
|
-
|
|
18
18
|
# The Noop circuit breaker is the `:circuit_breaker` used by default in
|
|
19
19
|
# the Throttler
|
|
20
20
|
#
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Freno
|
|
2
4
|
class Throttler
|
|
3
|
-
|
|
4
5
|
# An Instrumenter is an object that responds to
|
|
5
6
|
# `instrument(event_name, payload = {})` to receive events from the
|
|
6
7
|
# throttler.
|
|
@@ -10,7 +11,6 @@ module Freno
|
|
|
10
11
|
# the application.
|
|
11
12
|
#
|
|
12
13
|
module Instrumenter
|
|
13
|
-
|
|
14
14
|
# The Noop instrumenter is the `:instrumenter` used by default in the
|
|
15
15
|
# Throttler
|
|
16
16
|
#
|
|
@@ -18,7 +18,7 @@ module Freno
|
|
|
18
18
|
# provided.
|
|
19
19
|
#
|
|
20
20
|
class Noop
|
|
21
|
-
def self.instrument(
|
|
21
|
+
def self.instrument(_event_name, payload = {})
|
|
22
22
|
yield payload if block_given?
|
|
23
23
|
end
|
|
24
24
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Freno
|
|
2
4
|
class Throttler
|
|
3
|
-
|
|
4
5
|
# A Mapper is any object that responds to `call`, by receiving a context
|
|
5
6
|
# object and returning a list of strings, each of which corresponds to the
|
|
6
7
|
# store_name that will be checked in freno.
|
|
@@ -13,7 +14,6 @@ module Freno
|
|
|
13
14
|
# where that shards exist.
|
|
14
15
|
#
|
|
15
16
|
module Mapper
|
|
16
|
-
|
|
17
17
|
# The Identity mapper is the one used by default in the Throttler.
|
|
18
18
|
#
|
|
19
19
|
# It works by informing the throttler to check exact same stores that it
|
data/lib/freno/throttler.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "freno/client"
|
|
2
4
|
require "freno/throttler/errors"
|
|
3
5
|
require "freno/throttler/mapper"
|
|
@@ -5,7 +7,6 @@ require "freno/throttler/instrumenter"
|
|
|
5
7
|
require "freno/throttler/circuit_breaker"
|
|
6
8
|
|
|
7
9
|
module Freno
|
|
8
|
-
|
|
9
10
|
# Freno::Throttler is the class responsible for throttling writes to a cluster
|
|
10
11
|
# or a set of clusters. Throttling means to slow down the pace at which write
|
|
11
12
|
# operations occur by checking with freno whether all the clusters affected by
|
|
@@ -32,9 +33,17 @@ module Freno
|
|
|
32
33
|
# and sleep if any of the stores is not ok.
|
|
33
34
|
#
|
|
34
35
|
class Throttler
|
|
35
|
-
|
|
36
36
|
DEFAULT_WAIT_SECONDS = 0.5
|
|
37
37
|
DEFAULT_MAX_WAIT_SECONDS = 10
|
|
38
|
+
REQUIRED_ARGS = %i[
|
|
39
|
+
client
|
|
40
|
+
app
|
|
41
|
+
mapper
|
|
42
|
+
instrumenter
|
|
43
|
+
circuit_breaker
|
|
44
|
+
wait_seconds
|
|
45
|
+
max_wait_seconds
|
|
46
|
+
].freeze
|
|
38
47
|
|
|
39
48
|
attr_accessor :client,
|
|
40
49
|
:app,
|
|
@@ -90,14 +99,15 @@ module Freno
|
|
|
90
99
|
# seconds the throttler will wait in total for replicas to catch-up
|
|
91
100
|
# before raising a `WaitedTooLong` error.
|
|
92
101
|
#
|
|
93
|
-
def initialize(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
def initialize(
|
|
103
|
+
client: nil,
|
|
104
|
+
app: nil,
|
|
105
|
+
mapper: Mapper::Identity,
|
|
106
|
+
instrumenter: Instrumenter::Noop,
|
|
107
|
+
circuit_breaker: CircuitBreaker::Noop,
|
|
108
|
+
wait_seconds: DEFAULT_WAIT_SECONDS,
|
|
109
|
+
max_wait_seconds: DEFAULT_MAX_WAIT_SECONDS
|
|
110
|
+
)
|
|
101
111
|
@client = client
|
|
102
112
|
@app = app
|
|
103
113
|
@mapper = mapper
|
|
@@ -156,7 +166,7 @@ module Freno
|
|
|
156
166
|
instrument(:called, store_names: store_names)
|
|
157
167
|
waited = 0
|
|
158
168
|
|
|
159
|
-
|
|
169
|
+
loop do
|
|
160
170
|
unless circuit_breaker.allow_request?
|
|
161
171
|
instrument(:circuit_open, store_names: store_names, waited: waited)
|
|
162
172
|
raise CircuitOpen
|
|
@@ -172,11 +182,11 @@ module Freno
|
|
|
172
182
|
waited += wait_seconds
|
|
173
183
|
instrument(:waited, store_names: store_names, waited: waited, max: max_wait_seconds)
|
|
174
184
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
185
|
+
next unless waited > max_wait_seconds
|
|
186
|
+
|
|
187
|
+
instrument(:waited_too_long, store_names: store_names, waited: waited, max: max_wait_seconds)
|
|
188
|
+
circuit_breaker.failure
|
|
189
|
+
raise WaitedTooLong.new(waited_seconds: waited, max_wait_seconds: max_wait_seconds)
|
|
180
190
|
end
|
|
181
191
|
end
|
|
182
192
|
|
|
@@ -185,8 +195,7 @@ module Freno
|
|
|
185
195
|
def validate_args
|
|
186
196
|
errors = []
|
|
187
197
|
|
|
188
|
-
|
|
189
|
-
wait_seconds max_wait_seconds).each do |argument|
|
|
198
|
+
REQUIRED_ARGS.each do |argument|
|
|
190
199
|
errors << "#{argument} must be provided" unless send(argument)
|
|
191
200
|
end
|
|
192
201
|
|
|
@@ -194,17 +203,17 @@ module Freno
|
|
|
194
203
|
errors << "max_wait_seconds (#{max_wait_seconds}) has to be greather than wait_seconds (#{wait_seconds})"
|
|
195
204
|
end
|
|
196
205
|
|
|
197
|
-
raise ArgumentError
|
|
206
|
+
raise ArgumentError, errors.join("\n") if errors.any?
|
|
198
207
|
end
|
|
199
208
|
|
|
200
209
|
def all_stores_ok?(store_names, **options)
|
|
201
210
|
store_names.all? do |store_name|
|
|
202
211
|
client.check?(app: app, store_name: store_name, options: options)
|
|
203
212
|
end
|
|
204
|
-
rescue Freno::Error =>
|
|
205
|
-
instrument(:freno_errored, store_names: store_names, error:
|
|
213
|
+
rescue Freno::Error => error
|
|
214
|
+
instrument(:freno_errored, store_names: store_names, error: error)
|
|
206
215
|
circuit_breaker.failure
|
|
207
|
-
raise ClientError
|
|
216
|
+
raise ClientError, error
|
|
208
217
|
end
|
|
209
218
|
|
|
210
219
|
def wait
|
metadata
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: freno-client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- GitHub
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-10-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - "
|
|
17
|
+
- - "<"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '3'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- - "
|
|
24
|
+
- - "<"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
26
|
+
version: '3'
|
|
27
27
|
description: 'freno-client is a Ruby library that interacts with Freno using HTTP.
|
|
28
28
|
Freno is a throttling service and its source code is available at https://github.com/github/freno '
|
|
29
29
|
email: opensource+freno-client@github.com
|
|
@@ -31,9 +31,9 @@ executables: []
|
|
|
31
31
|
extensions: []
|
|
32
32
|
extra_rdoc_files: []
|
|
33
33
|
files:
|
|
34
|
+
- ".github/workflows/ruby.yml"
|
|
34
35
|
- ".gitignore"
|
|
35
36
|
- ".rubocop.yml"
|
|
36
|
-
- ".travis.yml"
|
|
37
37
|
- CODE_OF_CONDUCT.md
|
|
38
38
|
- CONTRIBUTING.md
|
|
39
39
|
- Gemfile
|
|
@@ -41,6 +41,9 @@ files:
|
|
|
41
41
|
- README.md
|
|
42
42
|
- Rakefile
|
|
43
43
|
- freno-client.gemspec
|
|
44
|
+
- gemfiles/faraday_0.gemfile
|
|
45
|
+
- gemfiles/faraday_1.gemfile
|
|
46
|
+
- gemfiles/faraday_2.gemfile
|
|
44
47
|
- lib/freno/client.rb
|
|
45
48
|
- lib/freno/client/errors.rb
|
|
46
49
|
- lib/freno/client/preconditions.rb
|
|
@@ -58,7 +61,8 @@ files:
|
|
|
58
61
|
homepage: https://github.com/github/freno-client
|
|
59
62
|
licenses:
|
|
60
63
|
- MIT
|
|
61
|
-
metadata:
|
|
64
|
+
metadata:
|
|
65
|
+
rubygems_mfa_required: 'true'
|
|
62
66
|
post_install_message:
|
|
63
67
|
rdoc_options: []
|
|
64
68
|
require_paths:
|
|
@@ -67,14 +71,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
67
71
|
requirements:
|
|
68
72
|
- - ">="
|
|
69
73
|
- !ruby/object:Gem::Version
|
|
70
|
-
version: 2.
|
|
74
|
+
version: 2.7.0
|
|
71
75
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
76
|
requirements:
|
|
73
77
|
- - ">="
|
|
74
78
|
- !ruby/object:Gem::Version
|
|
75
79
|
version: '0'
|
|
76
80
|
requirements: []
|
|
77
|
-
rubygems_version: 3.
|
|
81
|
+
rubygems_version: 3.3.7
|
|
78
82
|
signing_key:
|
|
79
83
|
specification_version: 4
|
|
80
84
|
summary: A library for interacting with Freno, the throttler service
|