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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f680a8adbf86c47eff50bcc58ae7b79993ef3f2f3c57ad99c9512937f92ba80
4
- data.tar.gz: 50cf87848d1284d171457112ed5a297fd063532f78ef0399e5d669b1bc3ded33
3
+ metadata.gz: 808823b23d76b3a540d9d17d2c6e28b428fd3cb387c941f79c749779393ac462
4
+ data.tar.gz: cf58a8db9c3d7fa2bea92727b3336a62fded79081723ee5e13555a72e6d68c62
5
5
  SHA512:
6
- metadata.gz: 6037e296652844e51cb469d3d6ca6dbb55e2baaa08c8c726b2885ad1b3ba6dd21857a85562d5b1491fb6b6cb86859ddc5fec0420f05089bb0c871c6ac69713cb
7
- data.tar.gz: 352a0abcea1e4fb28d2e920812a1d95a8051b62e52ff8a1cbaf05340aff3409150ad74d6292461908e4c7a9408dce7507910ff6ae4448f7cf62a9f1c048cd0f9
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
@@ -2,6 +2,7 @@
2
2
  /.bundle/
3
3
  /.yardoc
4
4
  /Gemfile.lock
5
+ /gemfiles/*.lock
5
6
  /_yardoc/
6
7
  /coverage/
7
8
  /doc/
data/.rubocop.yml CHANGED
@@ -1,179 +1,44 @@
1
- require: rubocop-performance
1
+ require:
2
+ - rubocop-minitest
3
+ - rubocop-performance
4
+ - rubocop-rake
2
5
 
3
6
  AllCops:
4
- DisabledByDefault: true
5
- TargetRubyVersion: 2.5
7
+ NewCops: enable
8
+ TargetRubyVersion: 2.7
6
9
 
7
- Bundler/DuplicatedGem:
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
- Naming/AsciiIdentifiers:
105
- Enabled: true
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
- Performance/Count:
114
- Enabled: true
115
- Performance/Detect:
116
- Enabled: true
117
- Performance/DoubleStartEndWith:
118
- Enabled: true
119
- Performance/EndWith:
120
- Enabled: true
121
- Performance/FlatMap:
122
- Enabled: true
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
- Security/Eval:
28
+ Naming/RescuedExceptionsVariableName:
134
29
  Enabled: true
30
+ PreferredName: error
135
31
 
136
- Style/ArrayJoin:
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", "~> 0.85.1", require: false
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
- # Freno Client [![Build Status](https://travis-ci.org/github/freno-client.svg?branch=master)](https://travis-ci.org/github/github/freno-client)
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 ruby library for throttling. You can use it in the following way:
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
  require "rake/testtask"
3
5
  require "rubocop/rake_task"
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
- DESC
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.5.0"
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", "~> 0"
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Freno
2
4
  Error = Class.new(StandardError)
3
5
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Freno
2
4
  class Client
3
5
  module Preconditions
4
- extend self
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.new(errors.join("\n")) unless errors.empty?
26
+ raise PreconditionNotMet, errors.join("\n") unless errors.empty?
25
27
  end
26
28
  end
27
29
 
@@ -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) || Hash.new
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 => ex
31
- raise Freno::Error.new(ex) if raise_on_timeout
30
+ rescue Faraday::TimeoutError => error
31
+ raise Freno::Error, error if raise_on_timeout
32
+
32
33
  Result.from_meaning(:request_timeout)
33
- rescue => ex
34
- raise Freno::Error.new(ex)
34
+ rescue StandardError => error
35
+ raise Freno::Error, error
35
36
  end
36
37
 
37
38
  protected
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "../request"
2
4
 
3
5
  module Freno
4
6
  class Client
5
7
  module Requests
6
8
  class Check < Request
7
-
8
9
  def initialize(**kwargs)
9
10
  super
10
11
 
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "../request"
2
4
 
3
5
  module Freno
4
6
  class Client
5
7
  module Requests
6
8
  class CheckRead < Request
7
-
8
9
  def initialize(**kwargs)
9
10
  super
10
11
 
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "../request"
2
4
 
3
5
  module Freno
4
6
  class Client
5
7
  module Requests
6
8
  class ReplicationDelay < Check
7
-
8
9
  protected
9
10
 
10
11
  def process_response(*)
@@ -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
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Freno
2
4
  class Client
3
- VERSION = "0.8.1"
5
+ VERSION = "0.8.2"
4
6
  end
5
7
  end
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: Requests::Check,
12
- check_read: Requests::CheckRead,
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(threshold:, app: default_app, store_type: default_store_type, store_name: default_store_name, options: {})
82
- perform :check_read, app: app, store_type: store_type, store_name: store_name, threshold: threshold, options: self.options.merge(options)
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(app: default_app, store_type: default_store_type, store_name: default_store_name, options: {})
93
- perform :replication_delay, app: app, store_type: store_type, store_name: store_name, options: self.options.merge(options)
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?(threshold:, app: default_app, store_type: default_store_type, store_name: default_store_name, options: {})
111
- check_read(threshold: threshold, app: app, store_type: store_type, store_name: store_name, options: self.options.merge(options)).ok?
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(request, with:)
169
- if request == :all
170
- requests = REQUESTS.keys
171
- else
172
- requests = Array(request)
173
- end
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..-1]).each do |decorator|
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,8 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "freno/client"
2
4
 
3
5
  module Freno
4
6
  class Throttler
5
-
6
7
  # Any throttler-related error.
7
8
  class Error < Freno::Error; end
8
9
 
@@ -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(event_name, payload = {})
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
@@ -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(client: nil,
94
- app: nil,
95
- mapper: Mapper::Identity,
96
- instrumenter: Instrumenter::Noop,
97
- circuit_breaker: CircuitBreaker::Noop,
98
- wait_seconds: DEFAULT_WAIT_SECONDS,
99
- max_wait_seconds: DEFAULT_MAX_WAIT_SECONDS)
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
- while true do # rubocop:disable Lint/LiteralInCondition
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
- if waited > max_wait_seconds
176
- instrument(:waited_too_long, store_names: store_names, waited: waited, max: max_wait_seconds)
177
- circuit_breaker.failure
178
- raise WaitedTooLong.new(waited_seconds: waited, max_wait_seconds: max_wait_seconds)
179
- end
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
- %i(client app mapper instrumenter circuit_breaker
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.new(errors.join("\n")) if errors.any?
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 => e
205
- instrument(:freno_errored, store_names: store_names, error: e)
213
+ rescue Freno::Error => error
214
+ instrument(:freno_errored, store_names: store_names, error: error)
206
215
  circuit_breaker.failure
207
- raise ClientError.new(e)
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.1
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: 2020-06-09 00:00:00.000000000 Z
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: '0'
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: '0'
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.5.0
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.1.2
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
data/.travis.yml DELETED
@@ -1,10 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.5
4
- - 2.6
5
- - 2.7
6
- - ruby-head
7
- matrix:
8
- allow_failures:
9
- - rvm: ruby-head
10
- script: bin/test