unleash 5.1.1 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/pull_request.yml +0 -2
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +10 -0
- data/README.md +93 -119
- data/lib/unleash/client.rb +21 -22
- data/lib/unleash/configuration.rb +2 -2
- data/lib/unleash/context.rb +35 -9
- data/lib/unleash/metrics_reporter.rb +12 -26
- data/lib/unleash/strategies.rb +14 -73
- data/lib/unleash/toggle_fetcher.rb +22 -56
- data/lib/unleash/variant.rb +6 -0
- data/lib/unleash/version.rb +1 -1
- data/lib/unleash.rb +1 -1
- data/unleash-client.gemspec +2 -2
- data/v6_MIGRATION_GUIDE.md +21 -0
- metadata +11 -26
- data/lib/unleash/activation_strategy.rb +0 -44
- data/lib/unleash/constraint.rb +0 -117
- data/lib/unleash/feature_toggle.rb +0 -253
- data/lib/unleash/metrics.rb +0 -41
- data/lib/unleash/strategy/application_hostname.rb +0 -26
- data/lib/unleash/strategy/base.rb +0 -16
- data/lib/unleash/strategy/default.rb +0 -13
- data/lib/unleash/strategy/flexible_rollout.rb +0 -64
- data/lib/unleash/strategy/gradual_rollout_random.rb +0 -24
- data/lib/unleash/strategy/gradual_rollout_sessionid.rb +0 -21
- data/lib/unleash/strategy/gradual_rollout_userid.rb +0 -21
- data/lib/unleash/strategy/remote_address.rb +0 -36
- data/lib/unleash/strategy/user_with_id.rb +0 -20
- data/lib/unleash/strategy/util.rb +0 -17
- data/lib/unleash/variant_definition.rb +0 -26
- data/lib/unleash/variant_override.rb +0 -44
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99ad38f03714b601bac152cb56373ed6ec9c881aee7f0a7bc538a26f777b81d4
|
4
|
+
data.tar.gz: b1b88a4cbd1bc03da617930046921e7c6ca1765506d65a38825c65d511b8a800
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f263e80e4bd7259f0dfa90cdcd28b902b06b125552927c67be2937d1bd26fcf9b44b07321efa8ad83973daaa29b53a540fdca1daafb9978ce05a4907b9fe402
|
7
|
+
data.tar.gz: 28994930969f57e529180a5562473066349d2c4a5db2f0b741d075adc5e229c0036a1b526464881e592d9cca1c2edbb0e9e4957bd61e8348bea5f7ab4bcd80db
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -13,6 +13,16 @@ Note: These changes are not considered notable:
|
|
13
13
|
|
14
14
|
## [Unreleased]
|
15
15
|
|
16
|
+
## [6.0.0] - 2024-09-25
|
17
|
+
#### Fixed
|
18
|
+
- Upgrade core engine library to support ARM on Linux
|
19
|
+
|
20
|
+
## [6.0.0.pre] - 2024-09-25
|
21
|
+
#### Changed
|
22
|
+
- No longer possible to override built in strategies with custom strategies (#152)
|
23
|
+
- No longer possible to access built in strategy's objects, these are now native code (#152)
|
24
|
+
- Core of the SDK swapped for Yggdrasil engine (#152)
|
25
|
+
|
16
26
|
## [5.1.1] - 2024-09-23
|
17
27
|
### Fixed
|
18
28
|
- increased accuracy of rollout distribution (#200)
|
data/README.md
CHANGED
@@ -6,42 +6,19 @@
|
|
6
6
|
|
7
7
|
Ruby client for the [Unleash](https://github.com/Unleash/unleash) feature management service.
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
- [Usage in a Rails Application](#usage-in-a-rails-application)
|
16
|
-
- [1. Add Initializer](#1-add-initializer)
|
17
|
-
- [1.a Initializer for standard Rails applications](#1a-initializer-for-standard-rails-applications)
|
18
|
-
- [1.b Add Initializer if using Puma in clustered mode](#1b-add-initializer-if-using-puma-in-clustered-mode)
|
19
|
-
- [with `preload_app!`](#with-preload_app)
|
20
|
-
- [without `preload_app!`](#without-preload_app)
|
21
|
-
- [1.c Add Initializer if using Phusion Passenger](#1c-add-initializer-if-using-phusion-passenger)
|
22
|
-
- [1.d Add Initializer hooks when using within Sidekiq](#1d-add-initializer-hooks-when-using-within-sidekiq)
|
23
|
-
- [2. Set Unleash::Context](#2-set-unleashcontext)
|
24
|
-
- [3. Sample usage](#3-sample-usage)
|
25
|
-
- [Variations](#variations)
|
26
|
-
- [Bootstrapping](#bootstrapping)
|
27
|
-
- [Client methods](#client-methods)
|
28
|
-
- [Local test client](#local-test-client)
|
29
|
-
- [Available Strategies](#available-strategies)
|
30
|
-
- [Custom Strategies](#custom-strategies)
|
31
|
-
- [Development](#development)
|
32
|
-
- [Releasing](#releasing)
|
33
|
-
- [Contributing](#contributing)
|
34
|
-
|
35
|
-
## Supported Ruby Interpreters
|
9
|
+
> **Migrating to v6**
|
10
|
+
>
|
11
|
+
> If you use [custom strategies](#custom-strategies) or override built-in ones, read the complete [migration guide](./v6_MIGRATION_GUIDE.md) before upgrading to v6.
|
12
|
+
|
13
|
+
|
14
|
+
## Supported Ruby interpreters
|
36
15
|
|
37
16
|
- MRI 3.3
|
38
17
|
- MRI 3.2
|
39
18
|
- MRI 3.1
|
40
19
|
- MRI 3.0
|
41
20
|
- MRI 2.7
|
42
|
-
- MRI 2.6
|
43
21
|
- jruby 9.4
|
44
|
-
- jruby 9.3
|
45
22
|
|
46
23
|
## Installation
|
47
24
|
|
@@ -59,72 +36,70 @@ Or install it yourself as:
|
|
59
36
|
|
60
37
|
$ gem install unleash
|
61
38
|
|
62
|
-
##
|
39
|
+
## Configuration
|
63
40
|
|
64
41
|
It is **required** to configure:
|
65
42
|
|
66
|
-
- `
|
67
|
-
- `
|
68
|
-
- `custom_http_headers` with `{'Authorization': '<
|
69
|
-
|
70
|
-
Please substitute the example `'https://unleash.herokuapp.com/api'` for the url of your own instance.
|
43
|
+
- `app_name` with the name of the running application
|
44
|
+
- `url` of your Unleash server
|
45
|
+
- `custom_http_headers` with `{'Authorization': '<YOUR_API_TOKEN>'}` when using Unleash v4+
|
71
46
|
|
72
47
|
It is **highly recommended** to configure:
|
73
48
|
|
74
|
-
- `instance_id` parameter with a unique identifier for the running instance
|
49
|
+
- `instance_id` parameter with a unique identifier for the running instance
|
75
50
|
|
76
51
|
```ruby
|
77
52
|
Unleash.configure do |config|
|
78
53
|
config.app_name = 'my_ruby_app'
|
79
|
-
config.url = '
|
80
|
-
config.custom_http_headers = {'Authorization': '<
|
54
|
+
config.url = '<YOUR_UNLEASH_URL>/api'
|
55
|
+
config.custom_http_headers = {'Authorization': '<YOUR_API_TOKEN>'}
|
81
56
|
end
|
82
57
|
```
|
83
58
|
|
84
59
|
or instantiate the client with the valid configuration:
|
85
60
|
|
86
61
|
```ruby
|
87
|
-
UNLEASH = Unleash::Client.new(url: '
|
62
|
+
UNLEASH = Unleash::Client.new(url: '<YOUR_UNLEASH_URL>/api', app_name: 'my_ruby_app', custom_http_headers: {'Authorization': '<YOUR_API_TOKEN>'})
|
88
63
|
```
|
89
64
|
|
90
65
|
## Dynamic custom HTTP headers
|
91
66
|
|
92
|
-
If you need custom HTTP headers that change during the lifetime of the client,
|
67
|
+
If you need custom HTTP headers that change during the lifetime of the client, you can pass `custom_http_headers` as a `Proc`.
|
93
68
|
|
94
69
|
```ruby
|
95
70
|
Unleash.configure do |config|
|
96
71
|
config.app_name = 'my_ruby_app'
|
97
|
-
config.url = '
|
72
|
+
config.url = '<YOUR_UNLEASH_URL>/api'
|
98
73
|
config.custom_http_headers = proc do
|
99
74
|
{
|
100
|
-
'Authorization': '<
|
75
|
+
'Authorization': '<YOUR_API_TOKEN>',
|
101
76
|
'X-Client-Request-Time': Time.now.iso8601
|
102
77
|
}
|
103
78
|
end
|
104
79
|
end
|
105
80
|
```
|
106
81
|
|
107
|
-
#### List of
|
82
|
+
#### List of arguments
|
108
83
|
|
109
|
-
| Argument | Description | Required? | Type | Default
|
84
|
+
| Argument | Description | Required? | Type | Default value |
|
110
85
|
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | --------------------------------- | ---------------------------------------------- |
|
111
86
|
| `url` | Unleash server URL. | Y | String | N/A |
|
112
87
|
| `app_name` | Name of your program. | Y | String | N/A |
|
113
|
-
| `instance_id` | Identifier for the running instance of program
|
114
|
-
| `environment` | Unleash context option
|
115
|
-
| `project_name` | Name of the project to retrieve
|
116
|
-
| `refresh_interval` | How often the
|
117
|
-
| `metrics_interval` | How often the
|
118
|
-
| `disable_client` | Disables all communication with the Unleash server, effectively taking it _offline_. If set, `is_enabled?`
|
88
|
+
| `instance_id` | Identifier for the running instance of your program—set this to be able trace where metrics are being collected from. | N | String | random UUID |
|
89
|
+
| `environment` | Unleash context option, for example, `prod` or `dev`. Not yet in use. **Not** the same as the SDK's [Unleash environment](https://docs.getunleash.io/reference/environments). | N | String | `default` |
|
90
|
+
| `project_name` | Name of the project to retrieve feature flags from. If not set, all feature flags will be retrieved. | N | String | nil |
|
91
|
+
| `refresh_interval` | How often the Unleash client should check with the server for configuration changes. | N | Integer | 15 |
|
92
|
+
| `metrics_interval` | How often the Unleash client should send metrics to server. | N | Integer | 60 |
|
93
|
+
| `disable_client` | Disables all communication with the Unleash server, effectively taking it _offline_. If set, `is_enabled?` always answer with the `default_value` and configuration validation is skipped. Will also forcefully set `disable_metrics` to `true`. Defeats the entire purpose of using Unleash, except when running tests. | N | Boolean | `false` |
|
119
94
|
| `disable_metrics` | Disables sending metrics to Unleash server. If the `disable_client` option is set to `true`, then this option will also be set to `true`, regardless of the value provided. | N | Boolean | `false` |
|
120
|
-
| `custom_http_headers` | Custom headers to send to Unleash. As of Unleash v4.0.0, the `Authorization` header is required. For example: `{'Authorization': '<
|
95
|
+
| `custom_http_headers` | Custom headers to send to Unleash. As of Unleash v4.0.0, the `Authorization` header is required. For example: `{'Authorization': '<YOUR_API_TOKEN>'}`. | N | Hash/Proc | {} |
|
121
96
|
| `timeout` | How long to wait for the connection to be established or wait in reading state (open_timeout/read_timeout) | N | Integer | 30 |
|
122
97
|
| `retry_limit` | How many consecutive failures in connecting to the Unleash server are allowed before giving up. The default is to retry indefinitely. | N | Float::INFINITY | 5 |
|
123
|
-
| `backup_file` | Filename to store the last known state from the Unleash server.
|
98
|
+
| `backup_file` | Filename to store the last known state from the Unleash server. It is best to not change this from the default. | N | String | `Dir.tmpdir + "/unleash-#{app_name}-repo.json` |
|
124
99
|
| `logger` | Specify a custom `Logger` class to handle logs for the Unleash client. | N | Class | `Logger.new(STDOUT)` |
|
125
100
|
| `log_level` | Change the log level for the `Logger` class. Constant from `Logger::Severity`. | N | Constant | `Logger::WARN` |
|
126
|
-
| `bootstrap_config` | Bootstrap config
|
127
|
-
| `strategies` | Strategies manager that holds all strategies and allows to add custom strategies | N | Unleash::Strategies | `Unleash::Strategies.new` |
|
101
|
+
| `bootstrap_config` | Bootstrap config for loading data on startup—useful for loading large states on startup without (or before) hitting the network. | N | Unleash::Bootstrap::Configuration | `nil` |
|
102
|
+
| `strategies` | Strategies manager that holds all strategies and allows to add custom strategies. | N | Unleash::Strategies | `Unleash::Strategies.new` |
|
128
103
|
|
129
104
|
For a more in-depth look, please see `lib/unleash/configuration.rb`.
|
130
105
|
|
@@ -133,13 +108,13 @@ For a more in-depth look, please see `lib/unleash/configuration.rb`.
|
|
133
108
|
| `UNLEASH_BOOTSTRAP_FILE` | File to read bootstrap data from |
|
134
109
|
| `UNLEASH_BOOTSTRAP_URL` | URL to read bootstrap data from |
|
135
110
|
|
136
|
-
## Usage in a plain Ruby
|
111
|
+
## Usage in a plain Ruby application
|
137
112
|
|
138
113
|
```ruby
|
139
114
|
require 'unleash'
|
140
115
|
require 'unleash/context'
|
141
116
|
|
142
|
-
@unleash = Unleash::Client.new(app_name: 'my_ruby_app', url: '
|
117
|
+
@unleash = Unleash::Client.new(app_name: 'my_ruby_app', url: '<YOUR_UNLEASH_URL>/api', custom_http_headers: { 'Authorization': '<YOUR_API_TOKEN>' })
|
143
118
|
|
144
119
|
feature_name = "AwesomeFeature"
|
145
120
|
unleash_context = Unleash::Context.new
|
@@ -158,7 +133,7 @@ else
|
|
158
133
|
end
|
159
134
|
```
|
160
135
|
|
161
|
-
## Usage in a Rails
|
136
|
+
## Usage in a Rails application
|
162
137
|
|
163
138
|
### 1. Add Initializer
|
164
139
|
|
@@ -183,10 +158,8 @@ UNLEASH = Unleash::Client.new
|
|
183
158
|
# Rails.configuration.unleash = Unleash::Client.new
|
184
159
|
```
|
185
160
|
|
186
|
-
For `config.instance_id` use a string with a unique identification for the running instance.
|
187
|
-
|
188
|
-
Or the docker container id, if you are running in docker.
|
189
|
-
If it is not set the client will generate an unique UUID for each execution.
|
161
|
+
For `config.instance_id` use a string with a unique identification for the running instance. For example, it could be the hostname if you only run one App per host, or the docker container ID, if you are running in Docker.
|
162
|
+
If not set, the client will generate a unique UUID for each execution.
|
190
163
|
|
191
164
|
To have it available in the `rails console` command as well, also add to the file above:
|
192
165
|
|
@@ -213,12 +186,12 @@ Then you may keep the client configuration still in `config/initializers/unleash
|
|
213
186
|
```ruby
|
214
187
|
Unleash.configure do |config|
|
215
188
|
config.app_name = Rails.application.class.parent.to_s
|
216
|
-
config.url = '
|
217
|
-
config.custom_http_headers = {'Authorization': '<
|
189
|
+
config.url = '<YOUR_UNLEASH_URL>/api'
|
190
|
+
config.custom_http_headers = {'Authorization': '<YOUR_API_TOKEN>'}
|
218
191
|
end
|
219
192
|
```
|
220
193
|
|
221
|
-
But you must ensure that the
|
194
|
+
But you must ensure that the Unleash client is instantiated only after the process is forked.
|
222
195
|
This is done by creating the client inside the `on_worker_boot` code block in `puma.rb` as below:
|
223
196
|
|
224
197
|
```ruby
|
@@ -241,14 +214,14 @@ end
|
|
241
214
|
|
242
215
|
By not using `preload_app!`:
|
243
216
|
|
244
|
-
-
|
245
|
-
-
|
217
|
+
- The `Rails` constant will **not** be available.
|
218
|
+
- Phased restarts will be possible.
|
246
219
|
|
247
220
|
You need to ensure that in `puma.rb`:
|
248
221
|
|
249
|
-
-
|
250
|
-
-
|
251
|
-
-
|
222
|
+
- The Unleash SDK is loaded with `require 'unleash'` explicitly, as it will not be pre-loaded.
|
223
|
+
- All parameters are set explicitly in the `on_worker_boot` block, as `config/initializers/unleash.rb` is not read.
|
224
|
+
- There are no references to `Rails` constant, as that is not yet available.
|
252
225
|
|
253
226
|
Example for `puma.rb`:
|
254
227
|
|
@@ -263,8 +236,8 @@ on_worker_boot do
|
|
263
236
|
|
264
237
|
::UNLEASH = Unleash::Client.new(
|
265
238
|
app_name: 'my_rails_app',
|
266
|
-
url: '
|
267
|
-
custom_http_headers: {'Authorization': '<
|
239
|
+
url: '<YOUR_UNLEASH_URL>/api',
|
240
|
+
custom_http_headers: {'Authorization': '<YOUR_API_TOKEN>'},
|
268
241
|
)
|
269
242
|
end
|
270
243
|
|
@@ -277,7 +250,7 @@ Note that we also added shutdown hooks in `on_worker_shutdown`, to ensure a clea
|
|
277
250
|
|
278
251
|
#### 1.c Add Initializer if using [Phusion Passenger](https://github.com/phusion/passenger)
|
279
252
|
|
280
|
-
The
|
253
|
+
The Unleash client needs to be configured and instantiated inside the `PhusionPassenger.on_event(:starting_worker_process)` code block due to [smart spawning](https://www.phusionpassenger.com/library/indepth/ruby/spawn_methods/#smart-spawning-caveats):
|
281
254
|
|
282
255
|
The initializer in `config/initializers/unleash.rb` should look like:
|
283
256
|
|
@@ -288,8 +261,8 @@ PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
|
288
261
|
config.app_name = Rails.application.class.parent.to_s
|
289
262
|
# config.instance_id = "#{Socket.gethostname}"
|
290
263
|
config.logger = Rails.logger
|
291
|
-
config.url = '
|
292
|
-
config.custom_http_headers = {'Authorization': '<
|
264
|
+
config.url = '<YOUR_UNLEASH_URL>/api'
|
265
|
+
config.custom_http_headers = {'Authorization': '<YOUR_API_TOKEN>'}
|
293
266
|
end
|
294
267
|
|
295
268
|
UNLEASH = Unleash::Client.new
|
@@ -299,7 +272,7 @@ end
|
|
299
272
|
|
300
273
|
#### 1.d Add Initializer hooks when using within [Sidekiq](https://github.com/mperham/sidekiq)
|
301
274
|
|
302
|
-
Note that in this case we require that the code block for `Unleash.configure` is set beforehand.
|
275
|
+
Note that in this case, we require that the code block for `Unleash.configure` is set beforehand.
|
303
276
|
For example in `config/initializers/unleash.rb`.
|
304
277
|
|
305
278
|
```ruby
|
@@ -316,7 +289,7 @@ end
|
|
316
289
|
|
317
290
|
### 2. Set Unleash::Context
|
318
291
|
|
319
|
-
|
292
|
+
Add the following method and callback in the application controller to have `@unleash_context` set for all requests:
|
320
293
|
|
321
294
|
Add in `app/controllers/application_controller.rb`:
|
322
295
|
|
@@ -333,7 +306,7 @@ Add in `app/controllers/application_controller.rb`:
|
|
333
306
|
end
|
334
307
|
```
|
335
308
|
|
336
|
-
|
309
|
+
Alternatively, you can add this method only to the controllers that use Unleash.
|
337
310
|
|
338
311
|
### 3. Sample usage
|
339
312
|
|
@@ -406,11 +379,11 @@ end
|
|
406
379
|
|
407
380
|
Note:
|
408
381
|
|
409
|
-
- The block/lambda/proc can use feature name and context as
|
382
|
+
- The block/lambda/proc can use the feature name and context as arguments.
|
410
383
|
- The client will evaluate the fallback function once per call of `is_enabled()`.
|
411
|
-
Please keep this in mind when creating your fallback function
|
384
|
+
Please keep this in mind when creating your fallback function.
|
412
385
|
- The returned value of the block should be a boolean.
|
413
|
-
However, the client will coerce the result to boolean via `!!`.
|
386
|
+
However, the client will coerce the result to a boolean via `!!`.
|
414
387
|
- If both a `default_value` and `fallback_function` are supplied,
|
415
388
|
the client will define the default value by `OR`ing the default value and the output of the fallback function.
|
416
389
|
|
@@ -442,21 +415,21 @@ Bootstrapping can be configured by providing a bootstrap configuration when init
|
|
442
415
|
|
443
416
|
```ruby
|
444
417
|
@unleash = Unleash::Client.new(
|
445
|
-
url: '
|
418
|
+
url: '<YOUR_UNLEASH_URL>/api',
|
446
419
|
app_name: 'my_ruby_app',
|
447
|
-
custom_http_headers: { 'Authorization': '<
|
420
|
+
custom_http_headers: { 'Authorization': '<YOUR_API_TOKEN>' },
|
448
421
|
bootstrap_config: Unleash::Bootstrap::Configuration.new({
|
449
|
-
url: "
|
450
|
-
url_headers: {'Authorization': '<
|
422
|
+
url: "<YOUR_UNLEASH_URL>/api/client/features",
|
423
|
+
url_headers: {'Authorization': '<YOUR_API_TOKEN>'}
|
451
424
|
})
|
452
425
|
)
|
453
426
|
```
|
454
427
|
|
455
428
|
The `Bootstrap::Configuration` initializer takes a hash with one of the following options specified:
|
456
429
|
|
457
|
-
- `file_path` - An absolute or relative path to a file containing a JSON string of the response body from the Unleash server. This can also be set
|
458
|
-
- `url` - A url pointing to an Unleash server's features endpoint, the code sample above is illustrative. This can also be set
|
459
|
-
- `url_headers` - Headers for the GET
|
430
|
+
- `file_path` - An absolute or relative path to a file containing a JSON string of the response body from the Unleash server. This can also be set through the `UNLEASH_BOOTSTRAP_FILE` environment variable.
|
431
|
+
- `url` - A url pointing to an Unleash server's features endpoint, the code sample above is illustrative. This can also be set through the `UNLEASH_BOOTSTRAP_URL` environment variable.
|
432
|
+
- `url_headers` - Headers for the GET HTTP request to the `url` above. Only used if the `url` parameter is also set. If this option isn't set then the bootstrapper will use the same url headers as the Unleash client.
|
460
433
|
- `data` - A raw JSON string as returned by the Unleash server.
|
461
434
|
- `block` - A lambda containing custom logic if you need it, an example is provided below.
|
462
435
|
|
@@ -470,13 +443,13 @@ The order of preference is as follows:
|
|
470
443
|
|
471
444
|
Example usage:
|
472
445
|
|
473
|
-
First
|
446
|
+
First, save the toggles locally:
|
474
447
|
|
475
448
|
```shell
|
476
|
-
curl -H 'Authorization: <
|
449
|
+
curl -H 'Authorization: <YOUR_API_TOKEN>' -XGET '<YOUR_UNLEASH_URL>/api' > ./default-toggles.json
|
477
450
|
```
|
478
451
|
|
479
|
-
|
452
|
+
Then use them on startup:
|
480
453
|
|
481
454
|
```ruby
|
482
455
|
|
@@ -486,8 +459,8 @@ custom_boostrapper = lambda {
|
|
486
459
|
|
487
460
|
@unleash = Unleash::Client.new(
|
488
461
|
app_name: 'my_ruby_app',
|
489
|
-
url: '
|
490
|
-
custom_http_headers: { 'Authorization': '<
|
462
|
+
url: '<YOUR_UNLEASH_URL>/api',
|
463
|
+
custom_http_headers: { 'Authorization': '<YOUR_API_TOKEN>' },
|
491
464
|
bootstrap_config: Unleash::Bootstrap::Configuration.new({
|
492
465
|
block: custom_boostrapper
|
493
466
|
})
|
@@ -499,19 +472,19 @@ Be aware that the client initializer will block until bootstrapping is complete.
|
|
499
472
|
|
500
473
|
#### Client methods
|
501
474
|
|
502
|
-
| Method
|
475
|
+
| Method name | Description | Return type |
|
503
476
|
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
|
504
|
-
| `is_enabled?` |
|
505
|
-
| `enabled?` |
|
506
|
-
| `if_enabled` |
|
507
|
-
| `is_disabled?` |
|
508
|
-
| `disabled?` |
|
509
|
-
| `if_disabled` |
|
510
|
-
| `get_variant` |
|
511
|
-
| `shutdown` |
|
512
|
-
| `shutdown!` |
|
513
|
-
|
514
|
-
For the full method signatures,
|
477
|
+
| `is_enabled?` | Checks if a feature toggle is enabled or not | Boolean |
|
478
|
+
| `enabled?` | A more idiomatic Ruby alias for the `is_enabled?` method | Boolean |
|
479
|
+
| `if_enabled` | Runs a code block, if a feature is enabled | `yield` |
|
480
|
+
| `is_disabled?` | Checks if feature toggle is enabled or not | Boolean |
|
481
|
+
| `disabled?` | A more idiomatic Ruby alias for the `is_disabled?` method | Boolean |
|
482
|
+
| `if_disabled` | Runs a code block, if a feature is disabled | `yield` |
|
483
|
+
| `get_variant` | Gets variant for a given feature | `Unleash::Variant` |
|
484
|
+
| `shutdown` | Saves metrics to disk, flushes metrics to server, and then kills `ToggleFetcher` and `MetricsReporter` threads—a safe shutdown, not generally needed in long-running applications, like web applications | nil |
|
485
|
+
| `shutdown!` | Kills `ToggleFetcher` and `MetricsReporter` threads immediately | nil |
|
486
|
+
|
487
|
+
For the full method signatures, see [client.rb](lib/unleash/client.rb).
|
515
488
|
|
516
489
|
## Local test client
|
517
490
|
|
@@ -523,9 +496,9 @@ bundle exec bin/unleash-client --help
|
|
523
496
|
bundle exec examples/simple.rb
|
524
497
|
```
|
525
498
|
|
526
|
-
## Available
|
499
|
+
## Available strategies
|
527
500
|
|
528
|
-
This client comes with
|
501
|
+
This client comes with all the required strategies out of the box:
|
529
502
|
|
530
503
|
- ApplicationHostnameStrategy
|
531
504
|
- DefaultStrategy
|
@@ -537,10 +510,10 @@ This client comes with the all the required strategies out of the box:
|
|
537
510
|
- UnknownStrategy
|
538
511
|
- UserWithIdStrategy
|
539
512
|
|
540
|
-
## Custom
|
513
|
+
## Custom strategies
|
541
514
|
|
542
|
-
|
543
|
-
In order for strategy to work correctly it should support two methods `name` and `is_enabled
|
515
|
+
You can add [custom activation strategies](https://docs.getunleash.io/advanced/custom_activation_strategy) using configuration.
|
516
|
+
In order for the strategy to work correctly it should support two methods `name` and `is_enabled?`.
|
544
517
|
|
545
518
|
```ruby
|
546
519
|
class MyCustomStrategy
|
@@ -575,16 +548,17 @@ To install this gem onto your local machine, run `bundle exec rake install`.
|
|
575
548
|
|
576
549
|
## Releasing
|
577
550
|
|
578
|
-
|
551
|
+
To release a new version, follow these steps:
|
579
552
|
|
580
|
-
|
581
|
-
-
|
582
|
-
|
583
|
-
-
|
584
|
-
-
|
585
|
-
|
586
|
-
|
587
|
-
|
553
|
+
1. Update version number:
|
554
|
+
- Increment the version number in the `./lib/unleash/version.rb` file according to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) guidelines.
|
555
|
+
2. Update documentation:
|
556
|
+
- If the update includes a major or minor version change, update the [Installation section](#installation) in [README.md](README.md).
|
557
|
+
- Update [CHANGELOG.md](CHANGELOG.md) following the format on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
558
|
+
3. Commit changes:
|
559
|
+
- Commit the changes with a message like: `chore: bump version to x.y.z.`
|
560
|
+
4. Release the gem:
|
561
|
+
- On the `main` branch, run `bundle exec rake release` to create a git tag for the new version, push commits and tags to origin, and publish `.gem` file to [rubygems.org](https://rubygems.org).
|
588
562
|
|
589
563
|
## Contributing
|
590
564
|
|
@@ -594,4 +568,4 @@ Be sure to run both `bundle exec rspec` and `bundle exec rubocop` in your branch
|
|
594
568
|
|
595
569
|
Please include tests with any pull requests, to avoid regressions.
|
596
570
|
|
597
|
-
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)
|
571
|
+
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).
|
data/lib/unleash/client.rb
CHANGED
@@ -2,7 +2,7 @@ require 'unleash/configuration'
|
|
2
2
|
require 'unleash/toggle_fetcher'
|
3
3
|
require 'unleash/metrics_reporter'
|
4
4
|
require 'unleash/scheduled_executor'
|
5
|
-
require 'unleash/
|
5
|
+
require 'unleash/variant'
|
6
6
|
require 'unleash/util/http'
|
7
7
|
require 'logger'
|
8
8
|
require 'time'
|
@@ -11,14 +11,17 @@ module Unleash
|
|
11
11
|
class Client
|
12
12
|
attr_accessor :fetcher_scheduled_executor, :metrics_scheduled_executor
|
13
13
|
|
14
|
+
# rubocop:disable Metrics/AbcSize
|
14
15
|
def initialize(*opts)
|
15
16
|
Unleash.configuration = Unleash::Configuration.new(*opts) unless opts.empty?
|
16
17
|
Unleash.configuration.validate!
|
17
18
|
|
18
19
|
Unleash.logger = Unleash.configuration.logger.clone
|
19
20
|
Unleash.logger.level = Unleash.configuration.log_level
|
21
|
+
Unleash.engine = YggdrasilEngine.new
|
22
|
+
Unleash.engine.register_custom_strategies(Unleash.configuration.strategies.custom_strategies)
|
20
23
|
|
21
|
-
Unleash.toggle_fetcher = Unleash::ToggleFetcher.new
|
24
|
+
Unleash.toggle_fetcher = Unleash::ToggleFetcher.new Unleash.engine
|
22
25
|
if Unleash.configuration.disable_client
|
23
26
|
Unleash.logger.warn "Unleash::Client is disabled! Will only return default (or bootstrapped if available) results!"
|
24
27
|
Unleash.logger.warn "Unleash::Client is disabled! Metrics and MetricsReporter are also disabled!"
|
@@ -30,6 +33,7 @@ module Unleash
|
|
30
33
|
start_toggle_fetcher
|
31
34
|
start_metrics unless Unleash.configuration.disable_metrics
|
32
35
|
end
|
36
|
+
# rubocop:enable Metrics/AbcSize
|
33
37
|
|
34
38
|
def is_enabled?(feature, context = nil, default_value_param = false, &fallback_blk)
|
35
39
|
Unleash.logger.debug "Unleash::Client.is_enabled? feature: #{feature} with context #{context}"
|
@@ -40,15 +44,16 @@ module Unleash
|
|
40
44
|
default_value_param
|
41
45
|
end
|
42
46
|
|
43
|
-
|
44
|
-
if
|
47
|
+
toggle_enabled = Unleash.engine.enabled?(feature, context)
|
48
|
+
if toggle_enabled.nil?
|
45
49
|
Unleash.logger.debug "Unleash::Client.is_enabled? feature: #{feature} not found"
|
50
|
+
Unleash.engine.count_toggle(feature, false)
|
46
51
|
return default_value
|
47
52
|
end
|
48
53
|
|
49
|
-
|
54
|
+
Unleash.engine.count_toggle(feature, toggle_enabled)
|
50
55
|
|
51
|
-
|
56
|
+
toggle_enabled
|
52
57
|
end
|
53
58
|
|
54
59
|
def is_disabled?(feature, context = nil, default_value_param = true, &fallback_blk)
|
@@ -71,23 +76,19 @@ module Unleash
|
|
71
76
|
end
|
72
77
|
|
73
78
|
def get_variant(feature, context = Unleash::Context.new, fallback_variant = disabled_variant)
|
74
|
-
Unleash.
|
75
|
-
|
76
|
-
toggle_as_hash = Unleash&.toggles&.select{ |toggle| toggle['name'] == feature }&.first
|
77
|
-
|
78
|
-
if toggle_as_hash.nil?
|
79
|
-
Unleash.logger.debug "Unleash::Client.get_variant feature: #{feature} not found"
|
80
|
-
return fallback_variant
|
81
|
-
end
|
82
|
-
|
83
|
-
toggle = Unleash::FeatureToggle.new(toggle_as_hash, Unleash&.segment_cache)
|
84
|
-
variant = toggle.get_variant(context, fallback_variant)
|
79
|
+
variant = Unleash.engine.get_variant(feature, context)
|
85
80
|
|
86
81
|
if variant.nil?
|
87
82
|
Unleash.logger.debug "Unleash::Client.get_variant variants for feature: #{feature} not found"
|
83
|
+
Unleash.engine.count_toggle(feature, false)
|
88
84
|
return fallback_variant
|
89
85
|
end
|
90
86
|
|
87
|
+
variant = Variant.new(variant)
|
88
|
+
|
89
|
+
Unleash.engine.count_variant(feature, variant.name)
|
90
|
+
Unleash.engine.count_toggle(feature, variant.feature_enabled)
|
91
|
+
|
91
92
|
# TODO: Add to README: name, payload, enabled (bool)
|
92
93
|
|
93
94
|
variant
|
@@ -96,7 +97,6 @@ module Unleash
|
|
96
97
|
# safe shutdown: also flush metrics to server and toggles to disk
|
97
98
|
def shutdown
|
98
99
|
unless Unleash.configuration.disable_client
|
99
|
-
Unleash.toggle_fetcher.save!
|
100
100
|
Unleash.reporter.post unless Unleash.configuration.disable_metrics
|
101
101
|
shutdown!
|
102
102
|
end
|
@@ -117,12 +117,12 @@ module Unleash
|
|
117
117
|
'appName': Unleash.configuration.app_name,
|
118
118
|
'instanceId': Unleash.configuration.instance_id,
|
119
119
|
'sdkVersion': "unleash-client-ruby:" + Unleash::VERSION,
|
120
|
-
'strategies': Unleash.strategies.
|
120
|
+
'strategies': Unleash.strategies.known_strategies,
|
121
121
|
'started': Time.now.iso8601(Unleash::TIME_RESOLUTION),
|
122
122
|
'interval': Unleash.configuration.metrics_interval_in_millis,
|
123
123
|
'platformName': RUBY_ENGINE,
|
124
124
|
'platformVersion': RUBY_VERSION,
|
125
|
-
'yggdrasilVersion':
|
125
|
+
'yggdrasilVersion': "0.13.2",
|
126
126
|
'specVersion': Unleash::CLIENT_SPECIFICATION_VERSION
|
127
127
|
}
|
128
128
|
end
|
@@ -140,7 +140,6 @@ module Unleash
|
|
140
140
|
end
|
141
141
|
|
142
142
|
def start_metrics
|
143
|
-
Unleash.toggle_metrics = Unleash::Metrics.new
|
144
143
|
Unleash.reporter = Unleash::MetricsReporter.new
|
145
144
|
self.metrics_scheduled_executor = Unleash::ScheduledExecutor.new(
|
146
145
|
'MetricsReporter',
|
@@ -166,7 +165,7 @@ module Unleash
|
|
166
165
|
end
|
167
166
|
|
168
167
|
def disabled_variant
|
169
|
-
@disabled_variant ||= Unleash::
|
168
|
+
@disabled_variant ||= Unleash::Variant.disabled_variant
|
170
169
|
end
|
171
170
|
|
172
171
|
def first_fetch_is_eager
|