unleash 4.6.0 → 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f7e5c9cc285cd8b5d030f115babe035a65540a63aea7f2c0500d845afe74af1
4
- data.tar.gz: ec93948ce1eed18fc20ac93e8a9bb944ae6080a1740f58910d6689305d1cc72e
3
+ metadata.gz: e5eec84ff0d0a4890c3cc4f4605bc67762c5d4e434a0068e8a95cc5dbad830c3
4
+ data.tar.gz: 622ca11c209b7c214bc9e4c0114f0f2ec536c678d7faf536d8d657142c7201fc
5
5
  SHA512:
6
- metadata.gz: cabaff808990418367c85b739b5994f3d0010ee61415b5d9e6dfcea9e3b808b3b9d9e6bd05d07a0fd9bacc9423d909e52393e1a42ea671a95acfa7e45b4c80f4
7
- data.tar.gz: fdb3553cb10738d0db2be4a8f1bbd01181eb32abcb790420cbd6961c7f0df76841e7abfa88a29a829554d0baa3374db2f46fe87e068f380187bdbcc94d77fc03
6
+ metadata.gz: 5ac3bd355cf79dc61be37bd9a2df183e89e95b5221914382ef767063eb831a528e48eb558556877c3f208abbb648acf9af029eb27b5c629d18f53823d77b03a0
7
+ data.tar.gz: 2f5f1af33f7e9b60016a8e3c8f6434fff6f8ddb4e0d3cd5cafa1cb03550536cd6d95caa964b2945485509a6286387a6395173fe782d178b42ea1dd67bc9c20ad
@@ -31,6 +31,7 @@ jobs:
31
31
  - jruby-9.4
32
32
  - jruby-9.3
33
33
  - jruby-9.2
34
+ - 3.3
34
35
  - 3.2
35
36
  - 3.1
36
37
  - '3.0'
@@ -41,7 +42,7 @@ jobs:
41
42
  needs:
42
43
  - lint
43
44
  steps:
44
- - uses: actions/checkout@v3
45
+ - uses: actions/checkout@v4
45
46
  - name: Set up Ruby ${{ matrix.ruby-version }}
46
47
  uses: ruby/setup-ruby@v1
47
48
  with:
@@ -50,7 +51,7 @@ jobs:
50
51
  - name: Install dependencies
51
52
  run: bundle install
52
53
  - name: Download test cases
53
- run: git clone --depth 5 --branch v4.5.1 https://github.com/Unleash/client-specification.git client-specification
54
+ run: git clone --depth 5 --branch v5.0.2 https://github.com/Unleash/client-specification.git client-specification
54
55
  - name: Run tests
55
56
  run: bundle exec rake
56
57
  env:
data/.rubocop.yml CHANGED
@@ -127,6 +127,8 @@ Layout/BeginEndAlignment:
127
127
  Enabled: true
128
128
  Layout/EmptyLinesAroundAttributeAccessor:
129
129
  Enabled: true
130
+ Layout/FirstHashElementIndentation:
131
+ EnforcedStyle: consistent
130
132
  Layout/SpaceAroundMethodCallOperator:
131
133
  Enabled: true
132
134
  Layout/MultilineMethodCallIndentation:
data/CHANGELOG.md CHANGED
@@ -13,6 +13,21 @@ Note: These changes are not considered notable:
13
13
 
14
14
  ## [Unreleased]
15
15
 
16
+ ## [5.0.1] - 2024-03-27
17
+ ### Changed
18
+ - make user-agent headers more descriptive (#168)
19
+
20
+ ### Fixed
21
+ - make client more resilient to non-conforming responses from `unleash-edge` (#162)
22
+ - while the unleash server provides always valid responses, (at least some versions of) unleash-edge can provide an unexpected JSON response (null instead of empty array).
23
+ - fixed the handling of the response, so we do not throw exceptions in this situation.
24
+
25
+ ## [5.0.0] - 2023-10-30
26
+ ### Added
27
+ - change seed for variantutils to ensure fair distribution (#160)
28
+ - client specification is [here](https://github.com/Unleash/client-specification/tree/v5.0.2/specifications)
29
+ - A new seed is introduced to ensure a fair distribution for variants, addressing the issue of skewed variant distribution due to using the same hash string for both gradual rollout and variant allocation.
30
+
16
31
  ## [4.6.0] - 2023-10-16
17
32
  ### Added
18
33
  - dependant toggles (#155)
data/README.md CHANGED
@@ -10,6 +10,7 @@ Leverage the [Unleash Server](https://github.com/Unleash/unleash) for powerful f
10
10
 
11
11
  ## Supported Ruby Interpreters
12
12
 
13
+ * MRI 3.3
13
14
  * MRI 3.2
14
15
  * MRI 3.1
15
16
  * MRI 3.0
@@ -25,7 +26,7 @@ Leverage the [Unleash Server](https://github.com/Unleash/unleash) for powerful f
25
26
  Add this line to your application's Gemfile:
26
27
 
27
28
  ```ruby
28
- gem 'unleash', '~> 4.6.0'
29
+ gem 'unleash', '~> 5.0.0'
29
30
  ```
30
31
 
31
32
  And then execute:
@@ -528,7 +529,7 @@ You can also run `bin/console` for an interactive prompt that will allow you to
528
529
  This SDK is also built against the Unleash Client Specification tests.
529
530
  To run the Ruby SDK against this test suite, you'll need to have a copy on your machine, you can clone the repository directly using:
530
531
 
531
- `git clone --depth 5 --branch v4.5.1 https://github.com/Unleash/client-specification.git client-specification`
532
+ `git clone --depth 5 --branch v5.0.2 https://github.com/Unleash/client-specification.git client-specification`
532
533
 
533
534
  After doing this, `rake spec` will also run the client specification tests.
534
535
 
@@ -555,3 +556,5 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/unleas
555
556
  Be sure to run both `bundle exec rspec` and `bundle exec rubocop` in your branch before creating a pull request.
556
557
 
557
558
  Please include tests with any pull requests, to avoid regressions.
559
+
560
+ Check out our guide for more information on how to build and scale [feature flag systems](https://docs.getunleash.io/topics/feature-flags/feature-flag-best-practices)
@@ -0,0 +1,63 @@
1
+ # example on how to extend the unleash client with opentelemetry by monkey patching it.
2
+ # to be added before initializing the client.
3
+ # in rails it could be added, for example, at:
4
+ # config/initializers/unleash.rb
5
+
6
+ require 'opentelemetry-api'
7
+ require 'unleash'
8
+
9
+ module UnleashExtensions
10
+ module OpenTelemetry
11
+ TRACER = ::OpenTelemetry.tracer_provider.tracer('Unleash-Client', Unleash::VERSION)
12
+
13
+ module Client
14
+ def initialize(*opts)
15
+ UnleashExtensions::OpenTelemetry::TRACER.in_span("#{self.class.name}##{__method__}") do |_span|
16
+ super(*opts)
17
+ end
18
+ end
19
+
20
+ def is_enabled?(feature, *args)
21
+ UnleashExtensions::OpenTelemetry::TRACER.in_span("#{self.class.name}##{__method__}") do |span|
22
+ result = super(feature, *args)
23
+
24
+ # OpenTelemetry::SemanticConventions::Trace::FEATURE_FLAG_* is not in the `opentelemetry-semantic_conventions` gem yet
25
+ span.add_attributes({
26
+ 'feature_flag.provider_name' => 'Unleash',
27
+ 'feature_flag.key' => feature,
28
+ 'feature_flag.variant' => result
29
+ })
30
+
31
+ result
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ module MetricsReporter
38
+ def post
39
+ UnleashExtensions::OpenTelemetry::TRACER.in_span("#{self.class.name}##{__method__}") do |_span|
40
+ super
41
+ end
42
+ end
43
+ end
44
+
45
+ module ToggleFetcher
46
+ def fetch
47
+ UnleashExtensions::OpenTelemetry::TRACER.in_span("#{self.class.name}##{__method__}") do |_span|
48
+ super
49
+ end
50
+ end
51
+
52
+ def save!
53
+ UnleashExtensions::OpenTelemetry::TRACER.in_span("#{self.class.name}##{__method__}") do |_span|
54
+ super
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ # MonkeyPatch here:
61
+ ::Unleash::Client.prepend UnleashExtensions::OpenTelemetry::Client
62
+ ::Unleash::MetricsReporter.prepend UnleashExtensions::OpenTelemetry::MetricsReporter
63
+ ::Unleash::ToggleFetcher.prepend UnleashExtensions::OpenTelemetry::ToggleFetcher
@@ -51,9 +51,10 @@ module Unleash
51
51
 
52
52
  def http_headers
53
53
  {
54
+ 'User-Agent' => "UnleashClientRuby/#{Unleash::VERSION} #{RUBY_ENGINE}/#{RUBY_VERSION} [#{RUBY_PLATFORM}]",
54
55
  'UNLEASH-INSTANCEID' => self.instance_id,
55
56
  'UNLEASH-APPNAME' => self.app_name,
56
- 'Unleash-Client-Spec' => '4.5.1'
57
+ 'Unleash-Client-Spec' => '5.0.2'
57
58
  }.merge!(generate_custom_http_headers)
58
59
  end
59
60
 
@@ -107,7 +107,7 @@ module Unleash
107
107
  context_value = context.get_by_name(self.context_name)
108
108
 
109
109
  v.map!(&:upcase) if self.case_insensitive
110
- context_value.upcase! if self.case_insensitive
110
+ context_value = context_value.upcase if self.case_insensitive
111
111
 
112
112
  OPERATORS[self.operator].call(context_value, v)
113
113
  end
@@ -163,6 +163,7 @@ module Unleash
163
163
  variant_weight = Unleash::Strategy::Util.get_normalized_number(
164
164
  variant_salt(context, stickiness),
165
165
  group_id,
166
+ Unleash::Strategy::Util::VARIANT_NORMALIZER_SEED,
166
167
  sum_variant_defs_weights(variant_definitions)
167
168
  )
168
169
  prev_weights = 0
@@ -188,7 +189,7 @@ module Unleash
188
189
  end
189
190
 
190
191
  def initialize_strategies(params, segment_map)
191
- params.fetch('strategies', [])
192
+ (params.fetch('strategies', []) || [])
192
193
  .select{ |s| s.has_key?('name') && Unleash.strategies.includes?(s['name']) }
193
194
  .map do |s|
194
195
  ActivationStrategy.new(
@@ -201,7 +202,7 @@ module Unleash
201
202
  end
202
203
 
203
204
  def resolve_variants(strategy)
204
- strategy.fetch("variants", [])
205
+ (strategy.fetch("variants", []) || [])
205
206
  .select{ |variant| variant.is_a?(Hash) && variant.has_key?("name") }
206
207
  .map do |variant|
207
208
  VariantDefinition.new(
@@ -24,7 +24,7 @@ module Unleash
24
24
  end
25
25
 
26
26
  group_id = params.fetch('groupId', '')
27
- normalized_number = Util.get_normalized_number(stickiness_id, group_id)
27
+ normalized_number = Util.get_normalized_number(stickiness_id, group_id, 0)
28
28
 
29
29
  return false if stickiness_id.nil?
30
30
 
@@ -14,7 +14,7 @@ module Unleash
14
14
  return false if context.session_id.nil? || context.session_id.empty?
15
15
 
16
16
  percentage = Integer(params['percentage'] || 0)
17
- (percentage.positive? && Util.get_normalized_number(context.session_id, params['groupId'] || "") <= percentage)
17
+ (percentage.positive? && Util.get_normalized_number(context.session_id, params['groupId'] || "", 0) <= percentage)
18
18
  end
19
19
  end
20
20
  end
@@ -14,7 +14,7 @@ module Unleash
14
14
  return false if context.user_id.nil? || context.user_id.empty?
15
15
 
16
16
  percentage = Integer(params['percentage'] || 0)
17
- (percentage.positive? && Util.get_normalized_number(context.user_id, params['groupId'] || "") <= percentage)
17
+ (percentage.positive? && Util.get_normalized_number(context.user_id, params['groupId'] || "", 0) <= percentage)
18
18
  end
19
19
  end
20
20
  end
@@ -6,10 +6,11 @@ module Unleash
6
6
  module_function
7
7
 
8
8
  NORMALIZER = 100
9
+ VARIANT_NORMALIZER_SEED = 86_028_157
9
10
 
10
11
  # convert the two strings () into a number between 1 and base (100 by default)
11
- def get_normalized_number(identifier, group_id, base = NORMALIZER)
12
- MurmurHash3::V32.str_hash("#{group_id}:#{identifier}") % base + 1
12
+ def get_normalized_number(identifier, group_id, seed, base = NORMALIZER)
13
+ MurmurHash3::V32.str_hash("#{group_id}:#{identifier}", seed) % base + 1
13
14
  end
14
15
  end
15
16
  end
@@ -1,3 +1,3 @@
1
1
  module Unleash
2
- VERSION = "4.6.0".freeze
2
+ VERSION = "5.0.1".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unleash
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.6.0
4
+ version: 5.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Renato Arruda
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-16 00:00:00.000000000 Z
11
+ date: 2024-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: murmurhash3
@@ -162,6 +162,7 @@ files:
162
162
  - bin/unleash-client
163
163
  - examples/bootstrap.rb
164
164
  - examples/default-toggles.json
165
+ - examples/extending_unleash_with_opentelemetry.rb
165
166
  - examples/simple.rb
166
167
  - lib/unleash.rb
167
168
  - lib/unleash/activation_strategy.rb
@@ -200,7 +201,7 @@ homepage: https://github.com/unleash/unleash-client-ruby
200
201
  licenses:
201
202
  - Apache-2.0
202
203
  metadata: {}
203
- post_install_message:
204
+ post_install_message:
204
205
  rdoc_options: []
205
206
  require_paths:
206
207
  - lib
@@ -215,8 +216,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
215
216
  - !ruby/object:Gem::Version
216
217
  version: '0'
217
218
  requirements: []
218
- rubygems_version: 3.3.15
219
- signing_key:
219
+ rubygems_version: 3.3.3
220
+ signing_key:
220
221
  specification_version: 4
221
222
  summary: Unleash feature toggle client.
222
223
  test_files: []