unleash 5.1.1 → 6.0.0
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/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
@@ -40,9 +40,9 @@ module Unleash
|
|
40
40
|
def validate!
|
41
41
|
return if self.disable_client
|
42
42
|
|
43
|
-
raise ArgumentError, "
|
43
|
+
raise ArgumentError, "app_name is a required parameter." if self.app_name.nil?
|
44
44
|
|
45
|
-
validate_custom_http_headers!(self.custom_http_headers)
|
45
|
+
validate_custom_http_headers!(self.custom_http_headers) unless self.url.nil?
|
46
46
|
end
|
47
47
|
|
48
48
|
def refresh_backup_file!
|
data/lib/unleash/context.rb
CHANGED
@@ -7,20 +7,36 @@ module Unleash
|
|
7
7
|
def initialize(params = {})
|
8
8
|
raise ArgumentError, "Unleash::Context must be initialized with a hash." unless params.is_a?(Hash)
|
9
9
|
|
10
|
-
self.app_name
|
11
|
-
self.environment = value_for(
|
12
|
-
self.user_id
|
13
|
-
self.session_id
|
14
|
-
self.remote_address = value_for(
|
15
|
-
self.current_time = value_for(
|
16
|
-
|
17
|
-
properties = value_for(
|
10
|
+
self.app_name = value_for("appName", params, Unleash&.configuration&.app_name)
|
11
|
+
self.environment = value_for("environment", params, Unleash&.configuration&.environment || "default")
|
12
|
+
self.user_id = value_for("userId", params)&.to_s
|
13
|
+
self.session_id = value_for("sessionId", params)
|
14
|
+
self.remote_address = value_for("remoteAddress", params)
|
15
|
+
self.current_time = value_for("currentTime", params, Time.now.utc.iso8601.to_s)
|
16
|
+
|
17
|
+
properties = value_for("properties", params)
|
18
18
|
self.properties = properties.is_a?(Hash) ? properties.transform_keys(&:to_sym) : {}
|
19
19
|
end
|
20
20
|
|
21
21
|
def to_s
|
22
22
|
"<Context: user_id=#{@user_id},session_id=#{@session_id},remote_address=#{@remote_address},properties=#{@properties}" \
|
23
|
-
|
23
|
+
",app_name=#{@app_name},environment=#{@environment},current_time=#{@current_time}>"
|
24
|
+
end
|
25
|
+
|
26
|
+
def as_json
|
27
|
+
{
|
28
|
+
appName: to_safe_value(self.app_name),
|
29
|
+
environment: to_safe_value(self.environment),
|
30
|
+
userId: to_safe_value(self.user_id),
|
31
|
+
sessionId: to_safe_value(self.session_id),
|
32
|
+
remoteAddress: to_safe_value(self.remote_address),
|
33
|
+
currentTime: to_safe_value(self.current_time),
|
34
|
+
properties: self.properties.transform_values{ |value| to_safe_value(value) }
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_json(*options)
|
39
|
+
as_json(*options).to_json(*options)
|
24
40
|
end
|
25
41
|
|
26
42
|
def to_h
|
@@ -52,6 +68,16 @@ module Unleash
|
|
52
68
|
params.values_at(key, key.to_sym, underscore(key), underscore(key).to_sym).compact.first || default_value
|
53
69
|
end
|
54
70
|
|
71
|
+
def to_safe_value(value)
|
72
|
+
return nil if value.nil?
|
73
|
+
|
74
|
+
if value.is_a?(Time)
|
75
|
+
value.utc.iso8601
|
76
|
+
else
|
77
|
+
value.to_s
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
55
81
|
# converts CamelCase to snake_case
|
56
82
|
def underscore(camel_cased_word)
|
57
83
|
camel_cased_word.to_s.gsub(/(.)([A-Z])/, '\1_\2').downcase
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'unleash/configuration'
|
2
|
-
require 'unleash/metrics'
|
3
2
|
require 'net/http'
|
4
3
|
require 'json'
|
5
4
|
require 'time'
|
@@ -15,52 +14,39 @@ module Unleash
|
|
15
14
|
end
|
16
15
|
|
17
16
|
def generate_report
|
18
|
-
|
17
|
+
metrics = Unleash&.engine&.get_metrics()
|
18
|
+
return nil if metrics.nil? || metrics.empty?
|
19
19
|
|
20
|
-
|
21
|
-
stop = now
|
22
|
-
self.last_time = now
|
23
|
-
|
24
|
-
report = {
|
25
|
-
'appName': Unleash.configuration.app_name,
|
26
|
-
'instanceId': Unleash.configuration.instance_id,
|
20
|
+
{
|
27
21
|
'platformName': RUBY_ENGINE,
|
28
22
|
'platformVersion': RUBY_VERSION,
|
29
|
-
'yggdrasilVersion':
|
23
|
+
'yggdrasilVersion': "0.13.2",
|
30
24
|
'specVersion': Unleash::CLIENT_SPECIFICATION_VERSION,
|
31
|
-
'
|
32
|
-
|
33
|
-
|
34
|
-
'toggles': Unleash.toggle_metrics.features
|
35
|
-
}
|
25
|
+
'appName': Unleash.configuration.app_name,
|
26
|
+
'instanceId': Unleash.configuration.instance_id,
|
27
|
+
'bucket': metrics
|
36
28
|
}
|
37
|
-
Unleash.toggle_metrics.reset
|
38
|
-
|
39
|
-
report
|
40
29
|
end
|
41
30
|
|
42
31
|
def post
|
43
32
|
Unleash.logger.debug "post() Report"
|
44
33
|
|
45
|
-
|
34
|
+
bucket = self.generate_report
|
35
|
+
if bucket.nil? && (Time.now - self.last_time < LONGEST_WITHOUT_A_REPORT) # and last time is less then 10 minutes...
|
46
36
|
Unleash.logger.debug "Report not posted to server, as it would have been empty. (and has been empty for up to 10 min)"
|
47
37
|
|
48
38
|
return
|
49
39
|
end
|
50
40
|
|
51
|
-
response = Unleash::Util::Http.post(Unleash.configuration.client_metrics_uri,
|
41
|
+
response = Unleash::Util::Http.post(Unleash.configuration.client_metrics_uri, bucket.to_json)
|
52
42
|
|
53
43
|
if ['200', '202'].include? response.code
|
54
44
|
Unleash.logger.debug "Report sent to unleash server successfully. Server responded with http code #{response.code}"
|
55
45
|
else
|
46
|
+
# :nocov:
|
56
47
|
Unleash.logger.error "Error when sending report to unleash server. Server responded with http code #{response.code}."
|
48
|
+
# :nocov:
|
57
49
|
end
|
58
50
|
end
|
59
|
-
|
60
|
-
private
|
61
|
-
|
62
|
-
def bucket_empty?
|
63
|
-
Unleash.toggle_metrics.features.empty?
|
64
|
-
end
|
65
51
|
end
|
66
52
|
end
|
data/lib/unleash/strategies.rb
CHANGED
@@ -1,92 +1,33 @@
|
|
1
|
-
require 'unleash/strategy/base'
|
2
|
-
Gem.find_files('unleash/strategy/**/*.rb').each{ |path| require path }
|
3
|
-
|
4
1
|
module Unleash
|
2
|
+
class DefaultOverrideError < RuntimeError
|
3
|
+
end
|
4
|
+
|
5
5
|
class Strategies
|
6
|
+
attr_accessor :strategies
|
7
|
+
|
6
8
|
def initialize
|
7
9
|
@strategies = {}
|
8
|
-
register_strategies
|
9
|
-
end
|
10
|
-
|
11
|
-
def keys
|
12
|
-
@strategies.keys
|
13
10
|
end
|
14
11
|
|
15
12
|
def includes?(name)
|
16
|
-
@strategies.has_key?(name.to_s)
|
17
|
-
end
|
18
|
-
|
19
|
-
def fetch(name)
|
20
|
-
raise Unleash::Strategy::NotImplemented, "Strategy is not implemented" unless (strategy = @strategies[name.to_s])
|
21
|
-
|
22
|
-
strategy
|
13
|
+
@strategies.has_key?(name.to_s) || DEFAULT_STRATEGIES.include?(name.to_s)
|
23
14
|
end
|
24
15
|
|
25
16
|
def add(strategy)
|
26
|
-
if
|
27
|
-
Unleash.logger.error "WARNING: Overriding built in strategy '#{strategy.name}'. OVERIDING BUILT IN STRATEGIES IS \
|
28
|
-
DEPRECATED AND WILL BE REMOVED IN A FUTURE RELEASE."
|
29
|
-
end
|
30
|
-
self.internal_add(strategy)
|
31
|
-
end
|
32
|
-
|
33
|
-
def []=(key, strategy)
|
34
|
-
warn_deprecated_registration(strategy, 'modifying Unleash::STRATEGIES')
|
35
|
-
@strategies[key.to_s] = strategy
|
36
|
-
end
|
17
|
+
raise DefaultOverrideError, "Cannot override a default strategy" if DEFAULT_STRATEGIES.include?(strategy.name)
|
37
18
|
|
38
|
-
def [](key)
|
39
|
-
@strategies[key.to_s]
|
40
|
-
end
|
41
|
-
|
42
|
-
def register_strategies
|
43
|
-
register_base_strategies
|
44
|
-
register_custom_strategies
|
45
|
-
end
|
46
|
-
|
47
|
-
protected
|
48
|
-
|
49
|
-
# Deprecated: Use Unleash.configuration to add custom strategies
|
50
|
-
def register_custom_strategies
|
51
|
-
Unleash::Strategy.constants
|
52
|
-
.select{ |c| Unleash::Strategy.const_get(c).is_a? Class }
|
53
|
-
.reject{ |c| ['NotImplemented', 'Base'].include?(c.to_s) } # Reject abstract classes
|
54
|
-
.map{ |c| Object.const_get("Unleash::Strategy::#{c}") }
|
55
|
-
.reject{ |c| DEFAULT_STRATEGIES.include?(c) } # Reject base classes
|
56
|
-
.each do |c|
|
57
|
-
strategy = c.new
|
58
|
-
warn_deprecated_registration(strategy, 'adding custom class into Unleash::Strategy namespace')
|
59
|
-
self.internal_add(strategy)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def register_base_strategies
|
64
|
-
DEFAULT_STRATEGIES.each{ |c| self.internal_add(c.new) }
|
65
|
-
end
|
66
|
-
|
67
|
-
def internal_add(strategy)
|
68
19
|
@strategies[strategy.name] = strategy
|
69
20
|
end
|
70
21
|
|
71
|
-
def
|
72
|
-
|
22
|
+
def custom_strategies
|
23
|
+
@strategies.values
|
73
24
|
end
|
74
25
|
|
75
|
-
|
76
|
-
|
77
|
-
Unleash::Strategy::Default,
|
78
|
-
Unleash::Strategy::FlexibleRollout,
|
79
|
-
Unleash::Strategy::GradualRolloutRandom,
|
80
|
-
Unleash::Strategy::GradualRolloutSessionId,
|
81
|
-
Unleash::Strategy::GradualRolloutUserId,
|
82
|
-
Unleash::Strategy::RemoteAddress,
|
83
|
-
Unleash::Strategy::UserWithId
|
84
|
-
].freeze
|
85
|
-
|
86
|
-
def warn_deprecated_registration(strategy, method)
|
87
|
-
warn "[DEPRECATED] Registering custom Unleash strategy by #{method} is deprecated.
|
88
|
-
Please use Unleash configuration to register custom strategy: " \
|
89
|
-
"`Unleash.configure {|c| c.strategies.add(#{strategy.class.name}.new) }`"
|
26
|
+
def known_strategies
|
27
|
+
@strategies.keys.map{ |key| { name: key } }
|
90
28
|
end
|
29
|
+
|
30
|
+
DEFAULT_STRATEGIES = ['applicationHostname', 'default', 'flexibleRollout', 'gradualRolloutRandom', 'gradualRolloutSessionId',
|
31
|
+
'gradualRolloutUserId', 'remoteAddress', 'userWithId'].freeze
|
91
32
|
end
|
92
33
|
end
|
@@ -2,15 +2,15 @@ require 'unleash/configuration'
|
|
2
2
|
require 'unleash/bootstrap/handler'
|
3
3
|
require 'net/http'
|
4
4
|
require 'json'
|
5
|
+
require 'yggdrasil_engine'
|
5
6
|
|
6
7
|
module Unleash
|
7
8
|
class ToggleFetcher
|
8
|
-
attr_accessor :
|
9
|
+
attr_accessor :toggle_engine, :toggle_lock, :toggle_resource, :etag, :retry_count
|
9
10
|
|
10
|
-
def initialize
|
11
|
+
def initialize(engine)
|
12
|
+
self.toggle_engine = engine
|
11
13
|
self.etag = nil
|
12
|
-
self.toggle_cache = nil
|
13
|
-
self.segment_cache = nil
|
14
14
|
self.toggle_lock = Mutex.new
|
15
15
|
self.toggle_resource = ConditionVariable.new
|
16
16
|
self.retry_count = 0
|
@@ -32,14 +32,6 @@ module Unleash
|
|
32
32
|
# once initialized, somewhere else you will want to start a loop with fetch()
|
33
33
|
end
|
34
34
|
|
35
|
-
def toggles
|
36
|
-
self.toggle_lock.synchronize do
|
37
|
-
# wait for resource, only if it is null
|
38
|
-
self.toggle_resource.wait(self.toggle_lock) if self.toggle_cache.nil?
|
39
|
-
return self.toggle_cache
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
35
|
# rename to refresh_from_server! ??
|
44
36
|
def fetch
|
45
37
|
Unleash.logger.debug "fetch()"
|
@@ -55,16 +47,14 @@ module Unleash
|
|
55
47
|
end
|
56
48
|
|
57
49
|
self.etag = response['ETag']
|
58
|
-
features = get_features(response.body)
|
59
50
|
|
60
51
|
# always synchronize with the local cache when fetching:
|
61
|
-
|
52
|
+
update_engine_state!(response.body)
|
62
53
|
|
63
|
-
|
64
|
-
save!
|
54
|
+
save! response.body
|
65
55
|
end
|
66
56
|
|
67
|
-
def save!
|
57
|
+
def save!(toggle_data)
|
68
58
|
Unleash.logger.debug "Will save toggles to disk now"
|
69
59
|
|
70
60
|
backup_file = Unleash.configuration.backup_file
|
@@ -72,7 +62,7 @@ module Unleash
|
|
72
62
|
|
73
63
|
self.toggle_lock.synchronize do
|
74
64
|
File.open(backup_file_tmp, "w") do |file|
|
75
|
-
file.write(
|
65
|
+
file.write(toggle_data)
|
76
66
|
end
|
77
67
|
File.rename(backup_file_tmp, backup_file)
|
78
68
|
end
|
@@ -84,23 +74,13 @@ module Unleash
|
|
84
74
|
|
85
75
|
private
|
86
76
|
|
87
|
-
def
|
88
|
-
|
89
|
-
self.
|
90
|
-
self.toggle_cache = features
|
91
|
-
end
|
92
|
-
|
93
|
-
# notify all threads waiting for this resource to no longer wait
|
94
|
-
self.toggle_resource.broadcast
|
77
|
+
def update_engine_state!(toggle_data)
|
78
|
+
self.toggle_lock.synchronize do
|
79
|
+
self.toggle_engine.take_state(toggle_data)
|
95
80
|
end
|
96
|
-
end
|
97
81
|
|
98
|
-
|
99
|
-
|
100
|
-
Unleash.logger.info "Updating toggles to main client, there has been a change in the server."
|
101
|
-
Unleash.toggles = self.toggles["features"]
|
102
|
-
Unleash.segment_cache = self.toggles["segments"]
|
103
|
-
end
|
82
|
+
# notify all threads waiting for this resource to no longer wait
|
83
|
+
self.toggle_resource.broadcast
|
104
84
|
end
|
105
85
|
|
106
86
|
def read!
|
@@ -108,42 +88,28 @@ module Unleash
|
|
108
88
|
backup_file = Unleash.configuration.backup_file
|
109
89
|
return nil unless File.exist?(backup_file)
|
110
90
|
|
111
|
-
|
112
|
-
|
113
|
-
update_running_client!
|
91
|
+
backup_data = File.read(backup_file)
|
92
|
+
update_engine_state!(backup_data)
|
114
93
|
rescue IOError => e
|
94
|
+
# :nocov:
|
115
95
|
Unleash.logger.error "Unable to read the backup_file: #{e}"
|
96
|
+
# :nocov:
|
116
97
|
rescue JSON::ParserError => e
|
98
|
+
# :nocov:
|
117
99
|
Unleash.logger.error "Unable to parse JSON from existing backup_file: #{e}"
|
100
|
+
# :nocov:
|
118
101
|
rescue StandardError => e
|
102
|
+
# :nocov:
|
119
103
|
Unleash.logger.error "Unable to extract valid data from backup_file. Exception thrown: #{e}"
|
104
|
+
# :nocov:
|
120
105
|
end
|
121
106
|
|
122
107
|
def bootstrap
|
123
108
|
bootstrap_payload = Unleash::Bootstrap::Handler.new(Unleash.configuration.bootstrap_config).retrieve_toggles
|
124
|
-
|
125
|
-
update_running_client!
|
109
|
+
update_engine_state! bootstrap_payload
|
126
110
|
|
127
111
|
# reset Unleash.configuration.bootstrap_data to free up memory, as we will never use it again
|
128
112
|
Unleash.configuration.bootstrap_config = nil
|
129
113
|
end
|
130
|
-
|
131
|
-
def build_segment_map(segments_array)
|
132
|
-
return {} if segments_array.nil?
|
133
|
-
|
134
|
-
segments_array.map{ |segment| [segment["id"], segment] }.to_h
|
135
|
-
end
|
136
|
-
|
137
|
-
# @param response_body [String]
|
138
|
-
def get_features(response_body)
|
139
|
-
response_hash = JSON.parse(response_body)
|
140
|
-
|
141
|
-
if response_hash['version'] >= 1
|
142
|
-
return { "features" => response_hash["features"], "segments" => build_segment_map(response_hash["segments"]) }
|
143
|
-
end
|
144
|
-
|
145
|
-
raise NotImplemented, "Version of features provided by unleash server" \
|
146
|
-
" is unsupported by this client."
|
147
|
-
end
|
148
114
|
end
|
149
115
|
end
|
data/lib/unleash/variant.rb
CHANGED
@@ -14,12 +14,18 @@ module Unleash
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def to_s
|
17
|
+
# :nocov:
|
17
18
|
"<Variant: name=#{self.name},enabled=#{self.enabled},payload=#{self.payload},feature_enabled=#{self.feature_enabled}>"
|
19
|
+
# :nocov:
|
18
20
|
end
|
19
21
|
|
20
22
|
def ==(other)
|
21
23
|
self.name == other.name && self.enabled == other.enabled && self.payload == other.payload \
|
22
24
|
&& self.feature_enabled == other.feature_enabled
|
23
25
|
end
|
26
|
+
|
27
|
+
def self.disabled_variant
|
28
|
+
Variant.new(name: 'disabled', enabled: false, feature_enabled: false)
|
29
|
+
end
|
24
30
|
end
|
25
31
|
end
|
data/lib/unleash/version.rb
CHANGED
data/lib/unleash.rb
CHANGED
@@ -10,7 +10,7 @@ module Unleash
|
|
10
10
|
TIME_RESOLUTION = 3
|
11
11
|
|
12
12
|
class << self
|
13
|
-
attr_accessor :configuration, :toggle_fetcher, :
|
13
|
+
attr_accessor :configuration, :toggle_fetcher, :reporter, :logger, :engine
|
14
14
|
end
|
15
15
|
|
16
16
|
self.configuration = Unleash::Configuration.new
|
data/unleash-client.gemspec
CHANGED
@@ -21,9 +21,9 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.bindir = 'bin'
|
22
22
|
spec.executables = spec.files.grep(%r{^bin/unleash}) { |f| File.basename(f) }
|
23
23
|
spec.require_paths = ["lib"]
|
24
|
-
spec.required_ruby_version = ">= 2.
|
24
|
+
spec.required_ruby_version = ">= 2.7"
|
25
25
|
|
26
|
-
spec.add_dependency "
|
26
|
+
spec.add_dependency "yggdrasil-engine", "~> 0.0.6"
|
27
27
|
|
28
28
|
spec.add_development_dependency "bundler", "~> 2.1"
|
29
29
|
spec.add_development_dependency "rake", "~> 12.3"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Migrating to Unleash-Client-Ruby 6.0.0
|
2
|
+
|
3
|
+
This guide highlights the key changes you should be aware of when upgrading to v6.0.0 of the Unleash client.
|
4
|
+
|
5
|
+
## Custom strategy changes
|
6
|
+
|
7
|
+
In version 6+, custom strategies cannot override the built-in strategies. Specifically, strategies `applicationHostname`, `default`, `flexibleRollout`, `gradualRolloutRandom`, `gradualRolloutSessionId`, `gradualRolloutUserId`, `remoteAddress` or `userWithId` throw an error on startup. Previously, creating a custom strategy would only generate a warning in the logs.
|
8
|
+
|
9
|
+
The deprecated `register_custom_strategies` method has been removed. You can continue to [register custom strategies](./README.md#custom-strategies) using configuration.
|
10
|
+
|
11
|
+
## Direct access to strategy objects
|
12
|
+
|
13
|
+
**Note:** If you're not using the method `known_strategies` this section doesn't affect you
|
14
|
+
|
15
|
+
The objects for base strategies are no longer directly accessible via the SDK. The `known_strategies` method only returns custom strategies registered by the user. To check if a custom strategy will override either a built-in or custom strategy, use the `includes?` method (returns false if the name is available).
|
16
|
+
|
17
|
+
It is strongly discouraged to access or modify any properties of the built-in strategies other than the name. In version 6+, this is a hard requirement.
|
18
|
+
|
19
|
+
## ARM requirements
|
20
|
+
|
21
|
+
Version 6.0.0 introduces a new dependency on a native binary. Currently, only ARM binaries for macOS are distributed. If you require ARM support for Linux or Windows, please open a GitHub issue.
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unleash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 6.0.0
|
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:
|
11
|
+
date: 2024-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: yggdrasil-engine
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.0.6
|
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: 0.0.6
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -166,7 +166,6 @@ files:
|
|
166
166
|
- examples/extending_unleash_with_opentelemetry.rb
|
167
167
|
- examples/simple.rb
|
168
168
|
- lib/unleash.rb
|
169
|
-
- lib/unleash/activation_strategy.rb
|
170
169
|
- lib/unleash/bootstrap/configuration.rb
|
171
170
|
- lib/unleash/bootstrap/handler.rb
|
172
171
|
- lib/unleash/bootstrap/provider/base.rb
|
@@ -174,36 +173,22 @@ files:
|
|
174
173
|
- lib/unleash/bootstrap/provider/from_url.rb
|
175
174
|
- lib/unleash/client.rb
|
176
175
|
- lib/unleash/configuration.rb
|
177
|
-
- lib/unleash/constraint.rb
|
178
176
|
- lib/unleash/context.rb
|
179
|
-
- lib/unleash/feature_toggle.rb
|
180
|
-
- lib/unleash/metrics.rb
|
181
177
|
- lib/unleash/metrics_reporter.rb
|
182
178
|
- lib/unleash/scheduled_executor.rb
|
183
179
|
- lib/unleash/spec_version.rb
|
184
180
|
- lib/unleash/strategies.rb
|
185
|
-
- lib/unleash/strategy/application_hostname.rb
|
186
|
-
- lib/unleash/strategy/base.rb
|
187
|
-
- lib/unleash/strategy/default.rb
|
188
|
-
- lib/unleash/strategy/flexible_rollout.rb
|
189
|
-
- lib/unleash/strategy/gradual_rollout_random.rb
|
190
|
-
- lib/unleash/strategy/gradual_rollout_sessionid.rb
|
191
|
-
- lib/unleash/strategy/gradual_rollout_userid.rb
|
192
|
-
- lib/unleash/strategy/remote_address.rb
|
193
|
-
- lib/unleash/strategy/user_with_id.rb
|
194
|
-
- lib/unleash/strategy/util.rb
|
195
181
|
- lib/unleash/toggle_fetcher.rb
|
196
182
|
- lib/unleash/util/http.rb
|
197
183
|
- lib/unleash/variant.rb
|
198
|
-
- lib/unleash/variant_definition.rb
|
199
|
-
- lib/unleash/variant_override.rb
|
200
184
|
- lib/unleash/version.rb
|
201
185
|
- unleash-client.gemspec
|
186
|
+
- v6_MIGRATION_GUIDE.md
|
202
187
|
homepage: https://github.com/unleash/unleash-client-ruby
|
203
188
|
licenses:
|
204
189
|
- Apache-2.0
|
205
190
|
metadata: {}
|
206
|
-
post_install_message:
|
191
|
+
post_install_message:
|
207
192
|
rdoc_options: []
|
208
193
|
require_paths:
|
209
194
|
- lib
|
@@ -211,15 +196,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
211
196
|
requirements:
|
212
197
|
- - ">="
|
213
198
|
- !ruby/object:Gem::Version
|
214
|
-
version: '2.
|
199
|
+
version: '2.7'
|
215
200
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
216
201
|
requirements:
|
217
202
|
- - ">="
|
218
203
|
- !ruby/object:Gem::Version
|
219
204
|
version: '0'
|
220
205
|
requirements: []
|
221
|
-
rubygems_version: 3.5.
|
222
|
-
signing_key:
|
206
|
+
rubygems_version: 3.5.6
|
207
|
+
signing_key:
|
223
208
|
specification_version: 4
|
224
209
|
summary: Unleash feature toggle client.
|
225
210
|
test_files: []
|
@@ -1,44 +0,0 @@
|
|
1
|
-
module Unleash
|
2
|
-
class ActivationStrategy
|
3
|
-
attr_accessor :name, :params, :constraints, :disabled, :variant_definitions
|
4
|
-
|
5
|
-
def initialize(name, params, constraints = [], variant_definitions = [])
|
6
|
-
self.name = name
|
7
|
-
self.disabled = false
|
8
|
-
|
9
|
-
if params.is_a?(Hash)
|
10
|
-
self.params = params
|
11
|
-
elsif params.nil?
|
12
|
-
self.params = {}
|
13
|
-
else
|
14
|
-
Unleash.logger.warn "Invalid params provided for ActivationStrategy (params:#{params})"
|
15
|
-
self.params = {}
|
16
|
-
end
|
17
|
-
|
18
|
-
if constraints.is_a?(Array) && constraints.all?{ |c| c.is_a?(Constraint) }
|
19
|
-
self.constraints = constraints
|
20
|
-
else
|
21
|
-
Unleash.logger.warn "Invalid constraints provided for ActivationStrategy (constraints: #{constraints})"
|
22
|
-
self.disabled = true
|
23
|
-
self.constraints = []
|
24
|
-
end
|
25
|
-
|
26
|
-
self.variant_definitions = valid_variant_definitions(variant_definitions)
|
27
|
-
end
|
28
|
-
|
29
|
-
def matches_context?(context)
|
30
|
-
self.constraints.any?{ |c| c.matches_context? context }
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def valid_variant_definitions(variant_definitions)
|
36
|
-
if variant_definitions.is_a?(Array) && variant_definitions.all?{ |variant_definition| variant_definition.is_a?(VariantDefinition) }
|
37
|
-
variant_definitions
|
38
|
-
else
|
39
|
-
Unleash.logger.warn "Invalid variant_definitions provided for ActivationStrategy (variant_definitions: #{variant_definitions})"
|
40
|
-
[]
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|