unleash 4.4.4 → 6.4.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/pull_request.yml +15 -15
  3. data/.rubocop.yml +5 -1
  4. data/CHANGELOG.md +147 -1
  5. data/README.md +161 -144
  6. data/bin/unleash-client +1 -1
  7. data/echo_client_spec_version.rb +3 -0
  8. data/examples/extending_unleash_with_opentelemetry.rb +63 -0
  9. data/examples/simple.rb +3 -4
  10. data/examples/streaming.rb +50 -0
  11. data/lib/unleash/bootstrap/handler.rb +2 -1
  12. data/lib/unleash/client.rb +47 -26
  13. data/lib/unleash/configuration.rb +48 -7
  14. data/lib/unleash/context.rb +35 -9
  15. data/lib/unleash/metrics_reporter.rb +39 -28
  16. data/lib/unleash/spec_version.rb +3 -0
  17. data/lib/unleash/strategies.rb +14 -61
  18. data/lib/unleash/streaming_client_executor.rb +85 -0
  19. data/lib/unleash/streaming_event_processor.rb +53 -0
  20. data/lib/unleash/toggle_fetcher.rb +29 -58
  21. data/lib/unleash/util/event_source_wrapper.rb +17 -0
  22. data/lib/unleash/util/http.rb +3 -2
  23. data/lib/unleash/variant.rb +11 -3
  24. data/lib/unleash/version.rb +1 -1
  25. data/lib/unleash.rb +2 -1
  26. data/unleash-client.gemspec +8 -4
  27. data/v6_MIGRATION_GUIDE.md +21 -0
  28. metadata +60 -26
  29. data/lib/unleash/activation_strategy.rb +0 -31
  30. data/lib/unleash/constraint.rb +0 -115
  31. data/lib/unleash/feature_toggle.rb +0 -187
  32. data/lib/unleash/metrics.rb +0 -41
  33. data/lib/unleash/strategy/application_hostname.rb +0 -26
  34. data/lib/unleash/strategy/base.rb +0 -16
  35. data/lib/unleash/strategy/default.rb +0 -13
  36. data/lib/unleash/strategy/flexible_rollout.rb +0 -64
  37. data/lib/unleash/strategy/gradual_rollout_random.rb +0 -24
  38. data/lib/unleash/strategy/gradual_rollout_sessionid.rb +0 -21
  39. data/lib/unleash/strategy/gradual_rollout_userid.rb +0 -21
  40. data/lib/unleash/strategy/remote_address.rb +0 -36
  41. data/lib/unleash/strategy/user_with_id.rb +0 -20
  42. data/lib/unleash/strategy/util.rb +0 -16
  43. data/lib/unleash/variant_definition.rb +0 -26
  44. data/lib/unleash/variant_override.rb +0 -44
@@ -0,0 +1,85 @@
1
+ require 'unleash/streaming_event_processor'
2
+ require 'unleash/util/event_source_wrapper'
3
+
4
+ module Unleash
5
+ class StreamingClientExecutor
6
+ attr_accessor :name, :event_source, :event_processor, :running
7
+
8
+ def initialize(name, engine)
9
+ self.name = name || 'StreamingClientExecutor'
10
+ self.event_source = nil
11
+ self.event_processor = Unleash::StreamingEventProcessor.new(engine)
12
+ self.running = false
13
+ end
14
+
15
+ def run(&_block)
16
+ start
17
+ end
18
+
19
+ def start
20
+ return if self.running || Unleash.configuration.disable_client
21
+
22
+ Unleash.logger.debug "Streaming client #{self.name} starting connection to: #{Unleash.configuration.fetch_toggles_uri}"
23
+
24
+ self.event_source = create_event_source
25
+ setup_event_handlers
26
+
27
+ self.running = true
28
+ Unleash.logger.debug "Streaming client #{self.name} connection established"
29
+ end
30
+
31
+ def stop
32
+ return unless self.running
33
+
34
+ Unleash.logger.debug "Streaming client #{self.name} stopping connection"
35
+ self.running = false
36
+ self.event_source&.close
37
+ self.event_source = nil
38
+ Unleash.logger.debug "Streaming client #{self.name} connection closed"
39
+ end
40
+
41
+ alias exit stop
42
+
43
+ def running?
44
+ self.running
45
+ end
46
+
47
+ private
48
+
49
+ def create_event_source
50
+ sse_client = Unleash::Util::EventSourceWrapper.client
51
+ if sse_client.nil?
52
+ raise "Streaming mode is configured but EventSource client is not available. " \
53
+ "Please install the 'ld-eventsource' gem or switch to polling mode."
54
+ end
55
+
56
+ headers = (Unleash.configuration.http_headers || {}).dup
57
+
58
+ sse_client.new(
59
+ Unleash.configuration.fetch_toggles_uri.to_s,
60
+ headers: headers,
61
+ read_timeout: 60,
62
+ reconnect_time: 2,
63
+ connect_timeout: 10,
64
+ logger: Unleash.logger
65
+ )
66
+ end
67
+
68
+ def setup_event_handlers
69
+ self.event_source.on_event do |event|
70
+ handle_event(event)
71
+ end
72
+
73
+ self.event_source.on_error do |error|
74
+ Unleash.logger.warn "Streaming client #{self.name} error: #{error}"
75
+ end
76
+ end
77
+
78
+ def handle_event(event)
79
+ self.event_processor.process_event(event)
80
+ rescue StandardError => e
81
+ Unleash.logger.error "Streaming client #{self.name} threw exception #{e.class}: '#{e}'"
82
+ Unleash.logger.debug "stacktrace: #{e.backtrace}"
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,53 @@
1
+ require 'json'
2
+
3
+ module Unleash
4
+ class StreamingEventProcessor
5
+ attr_accessor :toggle_engine, :mutex
6
+
7
+ def initialize(toggle_engine)
8
+ self.toggle_engine = toggle_engine
9
+ self.mutex = Mutex.new
10
+ end
11
+
12
+ def process_event(event)
13
+ case event.type.to_s
14
+ when 'unleash-connected'
15
+ Unleash.logger.debug "Streaming client connected"
16
+ handle_connected_event(event)
17
+ when 'unleash-updated'
18
+ Unleash.logger.debug "Received streaming update"
19
+ handle_updated_event(event)
20
+ else
21
+ Unleash.logger.debug "Received unknown event type: #{event.type}"
22
+ end
23
+ rescue StandardError => e
24
+ Unleash.logger.error "Error handling streaming event threw exception #{e.class}: '#{e}'"
25
+ Unleash.logger.debug "stacktrace: #{e.backtrace}"
26
+ end
27
+
28
+ def handle_delta_event(event_data)
29
+ self.mutex.synchronize do
30
+ self.toggle_engine.take_state(event_data)
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def handle_connected_event(event)
37
+ Unleash.logger.debug "Processing initial hydration data"
38
+ handle_updated_event(event)
39
+ end
40
+
41
+ def handle_updated_event(event)
42
+ handle_delta_event(event.data)
43
+
44
+ # TODO: update backup file
45
+ rescue JSON::ParserError => e
46
+ Unleash.logger.error "Unable to parse JSON from streaming event data. Exception thrown #{e.class}: '#{e}'"
47
+ Unleash.logger.debug "stacktrace: #{e.backtrace}"
48
+ rescue StandardError => e
49
+ Unleash.logger.error "Error processing delta update threw exception #{e.class}: '#{e}'"
50
+ Unleash.logger.debug "stacktrace: #{e.backtrace}"
51
+ end
52
+ end
53
+ 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 :toggle_cache, :toggle_lock, :toggle_resource, :etag, :retry_count, :segment_cache
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,39 +32,32 @@ 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()"
46
38
  return if Unleash.configuration.disable_client
47
39
 
48
- response = Unleash::Util::Http.get(Unleash.configuration.fetch_toggles_uri, etag)
40
+ headers = (Unleash.configuration.http_headers || {}).dup
41
+ headers.merge!({ 'UNLEASH-INTERVAL' => Unleash.configuration.refresh_interval.to_s })
42
+ response = Unleash::Util::Http.get(Unleash.configuration.fetch_toggles_uri, etag, headers)
49
43
 
50
44
  if response.code == '304'
51
45
  Unleash.logger.debug "No changes according to the unleash server, nothing to do."
52
46
  return
53
47
  elsif response.code != '200'
54
- raise IOError, "Unleash server returned a non 200/304 HTTP result."
48
+ raise IOError, "Unleash server returned unexpected HTTP response code #{response.code}."\
49
+ " Only handle response codes 200 (indicates changes) or 304 (no changes)."
55
50
  end
56
51
 
57
52
  self.etag = response['ETag']
58
- features = get_features(response.body)
59
53
 
60
54
  # always synchronize with the local cache when fetching:
61
- synchronize_with_local_cache!(features)
55
+ update_engine_state!(response.body)
62
56
 
63
- update_running_client!
64
- save!
57
+ save! response.body
65
58
  end
66
59
 
67
- def save!
60
+ def save!(toggle_data)
68
61
  Unleash.logger.debug "Will save toggles to disk now"
69
62
 
70
63
  backup_file = Unleash.configuration.backup_file
@@ -72,7 +65,7 @@ module Unleash
72
65
 
73
66
  self.toggle_lock.synchronize do
74
67
  File.open(backup_file_tmp, "w") do |file|
75
- file.write(self.toggle_cache.to_json)
68
+ file.write(toggle_data)
76
69
  end
77
70
  File.rename(backup_file_tmp, backup_file)
78
71
  end
@@ -84,23 +77,15 @@ module Unleash
84
77
 
85
78
  private
86
79
 
87
- def synchronize_with_local_cache!(features)
88
- if self.toggle_cache != features
89
- self.toggle_lock.synchronize do
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
80
+ def update_engine_state!(toggle_data)
81
+ self.toggle_lock.synchronize do
82
+ self.toggle_engine.take_state(toggle_data)
95
83
  end
96
- end
97
84
 
98
- def update_running_client!
99
- if Unleash.toggles != self.toggles["features"] || Unleash.segment_cache != self.toggles["segments"]
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
85
+ # notify all threads waiting for this resource to no longer wait
86
+ self.toggle_resource.broadcast
87
+ rescue StandardError => e
88
+ Unleash.logger.error "Failed to hydrate state: #{e.backtrace}"
104
89
  end
105
90
 
106
91
  def read!
@@ -108,42 +93,28 @@ module Unleash
108
93
  backup_file = Unleash.configuration.backup_file
109
94
  return nil unless File.exist?(backup_file)
110
95
 
111
- backup_as_hash = JSON.parse(File.read(backup_file))
112
- synchronize_with_local_cache!(backup_as_hash)
113
- update_running_client!
96
+ backup_data = File.read(backup_file)
97
+ update_engine_state!(backup_data)
114
98
  rescue IOError => e
99
+ # :nocov:
115
100
  Unleash.logger.error "Unable to read the backup_file: #{e}"
101
+ # :nocov:
116
102
  rescue JSON::ParserError => e
103
+ # :nocov:
117
104
  Unleash.logger.error "Unable to parse JSON from existing backup_file: #{e}"
105
+ # :nocov:
118
106
  rescue StandardError => e
107
+ # :nocov:
119
108
  Unleash.logger.error "Unable to extract valid data from backup_file. Exception thrown: #{e}"
109
+ # :nocov:
120
110
  end
121
111
 
122
112
  def bootstrap
123
113
  bootstrap_payload = Unleash::Bootstrap::Handler.new(Unleash.configuration.bootstrap_config).retrieve_toggles
124
- synchronize_with_local_cache! get_features bootstrap_payload
125
- update_running_client!
114
+ update_engine_state! bootstrap_payload
126
115
 
127
116
  # reset Unleash.configuration.bootstrap_data to free up memory, as we will never use it again
128
117
  Unleash.configuration.bootstrap_config = nil
129
118
  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
119
  end
149
120
  end
@@ -0,0 +1,17 @@
1
+ module Unleash
2
+ module Util
3
+ module EventSourceWrapper
4
+ def self.client
5
+ return nil if RUBY_ENGINE == 'jruby'
6
+
7
+ begin
8
+ require 'ld-eventsource'
9
+ SSE::Client
10
+ rescue LoadError => e
11
+ Unleash.logger.error "Failed to load ld-eventsource: #{e.message}"
12
+ nil
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -12,10 +12,10 @@ module Unleash
12
12
  http.request(request)
13
13
  end
14
14
 
15
- def self.post(uri, body)
15
+ def self.post(uri, body, headers_override = nil)
16
16
  http = http_connection(uri)
17
17
 
18
- request = Net::HTTP::Post.new(uri.request_uri, http_headers)
18
+ request = Net::HTTP::Post.new(uri.request_uri, http_headers(nil, headers_override))
19
19
  request.body = body
20
20
 
21
21
  http.request(request)
@@ -24,6 +24,7 @@ module Unleash
24
24
  def self.http_connection(uri)
25
25
  http = Net::HTTP.new(uri.host, uri.port)
26
26
  http.use_ssl = true if uri.scheme == 'https'
27
+ http.response_body_encoding = 'UTF-8' if http.respond_to?(:response_body_encoding=)
27
28
  http.open_timeout = Unleash.configuration.timeout # in seconds
28
29
  http.read_timeout = Unleash.configuration.timeout # in seconds
29
30
 
@@ -1,6 +1,6 @@
1
1
  module Unleash
2
2
  class Variant
3
- attr_accessor :name, :enabled, :payload
3
+ attr_accessor :name, :enabled, :payload, :feature_enabled
4
4
 
5
5
  def initialize(params = {})
6
6
  raise ArgumentError, "Variant initializer requires a hash." unless params.is_a?(Hash)
@@ -8,16 +8,24 @@ module Unleash
8
8
  self.name = params.values_at('name', :name).compact.first
9
9
  self.enabled = params.values_at('enabled', :enabled).compact.first || false
10
10
  self.payload = params.values_at('payload', :payload).compact.first
11
+ self.feature_enabled = params.values_at('feature_enabled', :feature_enabled).compact.first || false
11
12
 
12
13
  raise ArgumentError, "Variant requires a name." if self.name.nil?
13
14
  end
14
15
 
15
16
  def to_s
16
- "<Variant: name=#{self.name},enabled=#{self.enabled},payload=#{self.payload}>"
17
+ # :nocov:
18
+ "<Variant: name=#{self.name},enabled=#{self.enabled},payload=#{self.payload},feature_enabled=#{self.feature_enabled}>"
19
+ # :nocov:
17
20
  end
18
21
 
19
22
  def ==(other)
20
- self.name == other.name && self.enabled == other.enabled && self.payload == other.payload
23
+ self.name == other.name && self.enabled == other.enabled && self.payload == other.payload \
24
+ && self.feature_enabled == other.feature_enabled
25
+ end
26
+
27
+ def self.disabled_variant
28
+ Variant.new(name: 'disabled', enabled: false, feature_enabled: false)
21
29
  end
22
30
  end
23
31
  end
@@ -1,3 +1,3 @@
1
1
  module Unleash
2
- VERSION = "4.4.4".freeze
2
+ VERSION = "6.4.0".freeze
3
3
  end
data/lib/unleash.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'unleash/version'
2
+ require 'unleash/spec_version'
2
3
  require 'unleash/configuration'
3
4
  require 'unleash/strategies'
4
5
  require 'unleash/context'
@@ -9,7 +10,7 @@ module Unleash
9
10
  TIME_RESOLUTION = 3
10
11
 
11
12
  class << self
12
- attr_accessor :configuration, :toggle_fetcher, :toggles, :toggle_metrics, :reporter, :segment_cache, :logger
13
+ attr_accessor :configuration, :toggle_fetcher, :reporter, :logger, :engine
13
14
  end
14
15
 
15
16
  self.configuration = Unleash::Configuration.new
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
13
13
  spec.description = "This is the ruby client for Unleash, a powerful feature toggle system
14
14
  that gives you a great overview over all feature toggles across all your applications and services."
15
15
 
16
- spec.homepage = "https://github.com/unleash/unleash-client-ruby"
16
+ spec.homepage = "https://github.com/unleash/unleash-ruby-sdk"
17
17
 
18
18
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
19
  f.match(%r{^(test|spec|features)/})
@@ -21,9 +21,13 @@ 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.5"
24
+ spec.required_ruby_version = ">= 2.7"
25
25
 
26
- spec.add_dependency "murmurhash3", "~> 0.1.7"
26
+ spec.add_dependency "ld-eventsource", "2.2.4" unless RUBY_ENGINE == 'jruby'
27
+ spec.add_dependency "yggdrasil-engine", "~> 1.0.4"
28
+
29
+ spec.add_dependency "base64", "~> 0.3.0"
30
+ spec.add_dependency "logger", "~> 1.6"
27
31
 
28
32
  spec.add_development_dependency "bundler", "~> 2.1"
29
33
  spec.add_development_dependency "rake", "~> 12.3"
@@ -33,7 +37,7 @@ Gem::Specification.new do |spec|
33
37
 
34
38
  # rubocop:disable Gemspec/RubyVersionGlobalsUsage, Style/IfUnlessModifier
35
39
  if Gem::Version.new(RUBY_VERSION) > Gem::Version.new('3.0')
36
- spec.add_development_dependency "rubocop", "~> 1.51.0"
40
+ spec.add_development_dependency "rubocop", "~> 1.75"
37
41
  end
38
42
  # rubocop:enable Gemspec/RubyVersionGlobalsUsage, Style/IfUnlessModifier
39
43
 
@@ -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,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unleash
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.4
4
+ version: 6.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Renato Arruda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-05 00:00:00.000000000 Z
11
+ date: 2025-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: murmurhash3
14
+ name: ld-eventsource
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 2.2.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 2.2.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: yggdrasil-engine
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.4
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.4
41
+ - !ruby/object:Gem::Dependency
42
+ name: base64
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.3.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.3.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: logger
15
57
  requirement: !ruby/object:Gem::Requirement
16
58
  requirements:
17
59
  - - "~>"
18
60
  - !ruby/object:Gem::Version
19
- version: 0.1.7
61
+ version: '1.6'
20
62
  type: :runtime
21
63
  prerelease: false
22
64
  version_requirements: !ruby/object:Gem::Requirement
23
65
  requirements:
24
66
  - - "~>"
25
67
  - !ruby/object:Gem::Version
26
- version: 0.1.7
68
+ version: '1.6'
27
69
  - !ruby/object:Gem::Dependency
28
70
  name: bundler
29
71
  requirement: !ruby/object:Gem::Requirement
@@ -100,14 +142,14 @@ dependencies:
100
142
  requirements:
101
143
  - - "~>"
102
144
  - !ruby/object:Gem::Version
103
- version: 1.51.0
145
+ version: '1.75'
104
146
  type: :development
105
147
  prerelease: false
106
148
  version_requirements: !ruby/object:Gem::Requirement
107
149
  requirements:
108
150
  - - "~>"
109
151
  - !ruby/object:Gem::Version
110
- version: 1.51.0
152
+ version: '1.75'
111
153
  - !ruby/object:Gem::Dependency
112
154
  name: simplecov
113
155
  requirement: !ruby/object:Gem::Requirement
@@ -160,11 +202,13 @@ files:
160
202
  - bin/console
161
203
  - bin/setup
162
204
  - bin/unleash-client
205
+ - echo_client_spec_version.rb
163
206
  - examples/bootstrap.rb
164
207
  - examples/default-toggles.json
208
+ - examples/extending_unleash_with_opentelemetry.rb
165
209
  - examples/simple.rb
210
+ - examples/streaming.rb
166
211
  - lib/unleash.rb
167
- - lib/unleash/activation_strategy.rb
168
212
  - lib/unleash/bootstrap/configuration.rb
169
213
  - lib/unleash/bootstrap/handler.rb
170
214
  - lib/unleash/bootstrap/provider/base.rb
@@ -172,31 +216,21 @@ files:
172
216
  - lib/unleash/bootstrap/provider/from_url.rb
173
217
  - lib/unleash/client.rb
174
218
  - lib/unleash/configuration.rb
175
- - lib/unleash/constraint.rb
176
219
  - lib/unleash/context.rb
177
- - lib/unleash/feature_toggle.rb
178
- - lib/unleash/metrics.rb
179
220
  - lib/unleash/metrics_reporter.rb
180
221
  - lib/unleash/scheduled_executor.rb
222
+ - lib/unleash/spec_version.rb
181
223
  - lib/unleash/strategies.rb
182
- - lib/unleash/strategy/application_hostname.rb
183
- - lib/unleash/strategy/base.rb
184
- - lib/unleash/strategy/default.rb
185
- - lib/unleash/strategy/flexible_rollout.rb
186
- - lib/unleash/strategy/gradual_rollout_random.rb
187
- - lib/unleash/strategy/gradual_rollout_sessionid.rb
188
- - lib/unleash/strategy/gradual_rollout_userid.rb
189
- - lib/unleash/strategy/remote_address.rb
190
- - lib/unleash/strategy/user_with_id.rb
191
- - lib/unleash/strategy/util.rb
224
+ - lib/unleash/streaming_client_executor.rb
225
+ - lib/unleash/streaming_event_processor.rb
192
226
  - lib/unleash/toggle_fetcher.rb
227
+ - lib/unleash/util/event_source_wrapper.rb
193
228
  - lib/unleash/util/http.rb
194
229
  - lib/unleash/variant.rb
195
- - lib/unleash/variant_definition.rb
196
- - lib/unleash/variant_override.rb
197
230
  - lib/unleash/version.rb
198
231
  - unleash-client.gemspec
199
- homepage: https://github.com/unleash/unleash-client-ruby
232
+ - v6_MIGRATION_GUIDE.md
233
+ homepage: https://github.com/unleash/unleash-ruby-sdk
200
234
  licenses:
201
235
  - Apache-2.0
202
236
  metadata: {}
@@ -208,14 +242,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
208
242
  requirements:
209
243
  - - ">="
210
244
  - !ruby/object:Gem::Version
211
- version: '2.5'
245
+ version: '2.7'
212
246
  required_rubygems_version: !ruby/object:Gem::Requirement
213
247
  requirements:
214
248
  - - ">="
215
249
  - !ruby/object:Gem::Version
216
250
  version: '0'
217
251
  requirements: []
218
- rubygems_version: 3.3.15
252
+ rubygems_version: 3.5.22
219
253
  signing_key:
220
254
  specification_version: 4
221
255
  summary: Unleash feature toggle client.
@@ -1,31 +0,0 @@
1
- module Unleash
2
- class ActivationStrategy
3
- attr_accessor :name, :params, :constraints, :disabled
4
-
5
- def initialize(name, params, constraints = [])
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.each{ |c| c.is_a?(Constraint) }
19
- self.constraints = constraints
20
- else
21
- Unleash.logger.warn "Invalid constraints provided for ActivationStrategy (contraints: #{constraints})"
22
- self.disabled = true
23
- self.constraints = []
24
- end
25
- end
26
-
27
- def matches_context?(context)
28
- self.constraints.any?{ |c| c.matches_context? context }
29
- end
30
- end
31
- end