unleash 4.4.0 → 4.4.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: 5788566712ad3909e6707041673d359a4d9835b59c79bf0e0fac80c7c8a164ed
4
- data.tar.gz: 707f6875e73a10ef24fdce900aa7c179b0762eedda07ce83a41ea5ed76ba494f
3
+ metadata.gz: e8461b30f4a58518d73731731a7dfbc32041a5a017362319b9d8ba76d2cecb98
4
+ data.tar.gz: '06098a3f106f50b0ddad46e17bef57584918ecbefe88486009d95edbdb546550'
5
5
  SHA512:
6
- metadata.gz: 5d836f1c130e5db08fdac81f75cb938e93c060f997946ec80bd5819ad098a9b6d7a6d5628f88cd70144899bbe72ac1f5a1e802b4973b6ee0d24eda85e783fab3
7
- data.tar.gz: 69280e8af54ba2613ef3ae17206f0dfbd31a958d2595162dab71dd0d4cf5815d4dc3e023160c1edc1dbcaeea77d2cfd5f2e468af28051fe41b51dd77fae0f689
6
+ metadata.gz: ec0644f3bd93de7f75b06e44c059d39ff3ed87af00ee7ca17d1ad3a3e444626f190c4e26863167b116eda85ce0c01196542f8167f4494052fdae9b3e3e09e15c
7
+ data.tar.gz: 11764caf8ccd33c757cbd282a5e5f3d6d6b9dc7b70c29c0e9e196b512be3c1baee10abb21279358e7c7001a91b3825d5c42661910695e74e9e1585e2003c9b58
data/.github/stale.yml ADDED
@@ -0,0 +1 @@
1
+ _extends: .github
@@ -28,8 +28,10 @@ jobs:
28
28
  - ubuntu
29
29
  - macos
30
30
  ruby-version:
31
- - jruby-9.2
31
+ - jruby-9.4
32
32
  - jruby-9.3
33
+ - jruby-9.2
34
+ - 3.2
33
35
  - 3.1
34
36
  - '3.0'
35
37
  - 2.7
@@ -37,7 +39,7 @@ jobs:
37
39
  - 2.5
38
40
 
39
41
  steps:
40
- - uses: actions/checkout@v2
42
+ - uses: actions/checkout@v3
41
43
  - name: Set up Ruby ${{ matrix.ruby-version }}
42
44
  uses: ruby/setup-ruby@v1
43
45
  with:
data/.rubocop.yml CHANGED
@@ -6,10 +6,11 @@ AllCops:
6
6
  Naming/PredicateName:
7
7
  AllowedMethods:
8
8
  - is_enabled?
9
+ - is_disabled?
9
10
 
10
11
 
11
12
  Metrics/ClassLength:
12
- Max: 130
13
+ Max: 135
13
14
  Layout/LineLength:
14
15
  Max: 140
15
16
  Metrics/MethodLength:
@@ -22,7 +23,7 @@ Metrics/BlockLength:
22
23
  Metrics/AbcSize:
23
24
  Max: 30
24
25
  Metrics/CyclomaticComplexity:
25
- Max: 9
26
+ Max: 10
26
27
  Metrics/PerceivedComplexity:
27
28
  Max: 10
28
29
 
data/README.md CHANGED
@@ -10,11 +10,13 @@ Leverage the [Unleash Server](https://github.com/Unleash/unleash) for powerful f
10
10
 
11
11
  ## Supported Ruby Interpreters
12
12
 
13
+ * MRI 3.2
13
14
  * MRI 3.1
14
15
  * MRI 3.0
15
16
  * MRI 2.7
16
17
  * MRI 2.6
17
18
  * MRI 2.5
19
+ * jruby 9.4
18
20
  * jruby 9.3
19
21
  * jruby 9.2
20
22
 
@@ -23,7 +25,7 @@ Leverage the [Unleash Server](https://github.com/Unleash/unleash) for powerful f
23
25
  Add this line to your application's Gemfile:
24
26
 
25
27
  ```ruby
26
- gem 'unleash', '~> 4.0.0'
28
+ gem 'unleash', '~> 4.4.0'
27
29
  ```
28
30
 
29
31
  And then execute:
@@ -123,6 +125,12 @@ if @unleash.is_enabled?(feature_name, unleash_context)
123
125
  else
124
126
  puts " #{feature_name} is disabled according to unleash"
125
127
  end
128
+
129
+ if @unleash.is_disabled?(feature_name, unleash_context)
130
+ puts " #{feature_name} is disabled according to unleash"
131
+ else
132
+ puts " #{feature_name} is enabled according to unleash"
133
+ end
126
134
  ```
127
135
 
128
136
  ## Usage in a Rails Application
@@ -302,6 +310,9 @@ Then wherever in your application that you need a feature toggle, you can use:
302
310
  if UNLEASH.is_enabled? "AwesomeFeature", @unleash_context
303
311
  puts "AwesomeFeature is enabled"
304
312
  end
313
+ if UNLEASH.is_disabled? "AwesomeFeature", @unleash_context
314
+ puts "AwesomeFeature is disabled"
315
+ end
305
316
  ```
306
317
 
307
318
  or if client is set in `Rails.configuration.unleash`:
@@ -310,6 +321,9 @@ or if client is set in `Rails.configuration.unleash`:
310
321
  if Rails.configuration.unleash.is_enabled? "AwesomeFeature", @unleash_context
311
322
  puts "AwesomeFeature is enabled"
312
323
  end
324
+ if Rails.configuration.unleash.is_disabled? "AwesomeFeature", @unleash_context
325
+ puts "AwesomeFeature is enabled"
326
+ end
313
327
  ```
314
328
 
315
329
  If the feature is not found in the server, it will by default return false.
@@ -443,6 +457,9 @@ Method Name | Description | Return Type |
443
457
  `is_enabled?` | Check if feature toggle is to be enabled or not. | Boolean |
444
458
  `enabled?` | Alias to the `is_enabled?` method. But more ruby idiomatic. | Boolean |
445
459
  `if_enabled` | Run a code block, if a feature is enabled. | `yield` |
460
+ `is_disabled?` | Check if feature toggle is to be enabled or not. | Boolean |
461
+ `disabled?` | Alias to the `is_disabled?` method. But more ruby idiomatic. | Boolean |
462
+ `if_disabled` | Run a code block, if a feature is disabled. | `yield` |
446
463
  `get_variant` | Get variant for a given feature | `Unleash::Variant` |
447
464
  `shutdown` | Save metrics to disk, flush metrics to server, and then kill ToggleFetcher and MetricsReporter threads. A safe shutdown. Not really useful in long running applications, like web applications. | nil |
448
465
  `shutdown!` | Kill ToggleFetcher and MetricsReporter threads immediately. | nil |
@@ -475,7 +492,7 @@ This client comes with the all the required strategies out of the box:
475
492
 
476
493
  ## Custom Strategies
477
494
 
478
- Client allows to add [custom activation strategies](https://docs.getunleash.io/advanced/custom_activation_strategy) using configuration.
495
+ Client allows to add [custom activation strategies](https://docs.getunleash.io/advanced/custom_activation_strategy) using configuration.
479
496
  In order for strategy to work correctly it should support two methods `name` and `is_enabled?`
480
497
 
481
498
  ```ruby
@@ -483,7 +500,7 @@ class MyCustomStrategy
483
500
  def name
484
501
  'muCustomStrategy'
485
502
  end
486
-
503
+
487
504
  def is_enabled?(params = {}, context = nil)
488
505
  true
489
506
  end
@@ -498,6 +515,12 @@ end
498
515
 
499
516
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
500
517
 
518
+ This SDK is also built against the Unleash Client Specification tests. 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:
519
+
520
+ `git clone --depth 5 --branch v4.2.2 https://github.com/Unleash/client-specification.git client-specification`
521
+
522
+ After doing this, `rake spec` will also run the client specification tests.
523
+
501
524
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
502
525
 
503
526
 
@@ -50,14 +50,25 @@ module Unleash
50
50
  toggle.is_enabled?(context)
51
51
  end
52
52
 
53
+ def is_disabled?(feature, context = nil, default_value_param = true, &fallback_blk)
54
+ !is_enabled?(feature, context, !default_value_param, &fallback_blk)
55
+ end
56
+
53
57
  # enabled? is a more ruby idiomatic method name than is_enabled?
54
58
  alias enabled? is_enabled?
59
+ # disabled? is a more ruby idiomatic method name than is_disabled?
60
+ alias disabled? is_disabled?
55
61
 
56
62
  # execute a code block (passed as a parameter), if is_enabled? is true.
57
63
  def if_enabled(feature, context = nil, default_value = false, &blk)
58
64
  yield(blk) if is_enabled?(feature, context, default_value)
59
65
  end
60
66
 
67
+ # execute a code block (passed as a parameter), if is_disabled? is true.
68
+ def if_disabled(feature, context = nil, default_value = true, &blk)
69
+ yield(blk) if is_disabled?(feature, context, default_value)
70
+ end
71
+
61
72
  def get_variant(feature, context = Unleash::Context.new, fallback_variant = disabled_variant)
62
73
  Unleash.logger.debug "Unleash::Client.get_variant for feature: #{feature} with context #{context}"
63
74
 
@@ -43,6 +43,7 @@ module Unleash
43
43
 
44
44
  def matches_context?(context)
45
45
  Unleash.logger.debug "Unleash::Constraint matches_context? value: #{self.value} context.get_by_name(#{self.context_name})"
46
+ return false if context.nil?
46
47
 
47
48
  match = matches_constraint?(context)
48
49
  self.inverted ? !match : match
@@ -9,7 +9,7 @@ module Unleash
9
9
 
10
10
  self.app_name = value_for('appName', params, Unleash&.configuration&.app_name)
11
11
  self.environment = value_for('environment', params, Unleash&.configuration&.environment || 'default')
12
- self.user_id = value_for('userId', params)
12
+ self.user_id = value_for('userId', params)&.to_s
13
13
  self.session_id = value_for('sessionId', params)
14
14
  self.remote_address = value_for('remoteAddress', params)
15
15
  self.current_time = value_for('currentTime', params, Time.now.utc.iso8601.to_s)
@@ -37,12 +37,11 @@ module Unleash
37
37
 
38
38
  context = ensure_valid_context(context)
39
39
 
40
- return Unleash::FeatureToggle.disabled_variant unless self.enabled && am_enabled?(context)
41
- return Unleash::FeatureToggle.disabled_variant if sum_variant_defs_weights <= 0
42
-
43
- variant = variant_from_override_match(context) || variant_from_weights(context, resolve_stickiness)
40
+ toggle_enabled = am_enabled?(context)
41
+ variant = resolve_variant(context, toggle_enabled)
44
42
 
45
- Unleash.toggle_metrics.increment_variant(self.name, variant.name) unless Unleash.configuration.disable_metrics
43
+ choice = toggle_enabled ? :yes : :no
44
+ Unleash.toggle_metrics.increment_variant(self.name, choice, variant.name) unless Unleash.configuration.disable_metrics
46
45
  variant
47
46
  end
48
47
 
@@ -52,6 +51,13 @@ module Unleash
52
51
 
53
52
  private
54
53
 
54
+ def resolve_variant(context, toggle_enabled)
55
+ return Unleash::FeatureToggle.disabled_variant unless toggle_enabled
56
+ return Unleash::FeatureToggle.disabled_variant if sum_variant_defs_weights <= 0
57
+
58
+ variant_from_override_match(context) || variant_from_weights(context, resolve_stickiness)
59
+ end
60
+
55
61
  def resolve_stickiness
56
62
  self.variant_definitions&.map(&:stickiness)&.compact&.first || "default"
57
63
  end
@@ -1,33 +1,41 @@
1
1
  module Unleash
2
2
  class Metrics
3
- attr_accessor :features
4
-
5
- # NOTE: no mutexes for features
3
+ attr_accessor :features, :features_lock
6
4
 
7
5
  def initialize
8
6
  self.features = {}
7
+ self.features_lock = Mutex.new
9
8
  end
10
9
 
11
10
  def to_s
12
- self.features.to_json
11
+ self.features_lock.synchronize do
12
+ return self.features.to_json
13
+ end
13
14
  end
14
15
 
15
16
  def increment(feature, choice)
16
17
  raise "InvalidArgument choice must be :yes or :no" unless [:yes, :no].include? choice
17
18
 
18
- self.features[feature] = { yes: 0, no: 0 } unless self.features.include? feature
19
- self.features[feature][choice] += 1
19
+ self.features_lock.synchronize do
20
+ self.features[feature] = { yes: 0, no: 0 } unless self.features.include? feature
21
+ self.features[feature][choice] += 1
22
+ end
20
23
  end
21
24
 
22
- def increment_variant(feature, variant)
23
- self.features[feature] = { yes: 0, no: 0 } unless self.features.include? feature
24
- self.features[feature]['variant'] = {} unless self.features[feature].include? 'variant'
25
- self.features[feature]['variant'][variant] = 0 unless self.features[feature]['variant'].include? variant
26
- self.features[feature]['variant'][variant] += 1
25
+ def increment_variant(feature, choice, variant)
26
+ self.features_lock.synchronize do
27
+ self.features[feature] = { yes: 0, no: 0 } unless self.features.include? feature
28
+ self.features[feature][choice] += 1
29
+ self.features[feature]['variant'] = {} unless self.features[feature].include? 'variant'
30
+ self.features[feature]['variant'][variant] = 0 unless self.features[feature]['variant'].include? variant
31
+ self.features[feature]['variant'][variant] += 1
32
+ end
27
33
  end
28
34
 
29
35
  def reset
30
- self.features = {}
36
+ self.features_lock.synchronize do
37
+ self.features = {}
38
+ end
31
39
  end
32
40
  end
33
41
  end
@@ -1,3 +1,3 @@
1
1
  module Unleash
2
- VERSION = "4.4.0".freeze
2
+ VERSION = "4.4.2".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.4.0
4
+ version: 4.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Renato Arruda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-19 00:00:00.000000000 Z
11
+ date: 2023-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: murmurhash3
@@ -146,6 +146,7 @@ executables:
146
146
  extensions: []
147
147
  extra_rdoc_files: []
148
148
  files:
149
+ - ".github/stale.yml"
149
150
  - ".github/workflows/add-to-project.yml"
150
151
  - ".github/workflows/pull_request.yml"
151
152
  - ".gitignore"