launchdarkly-server-sdk 6.3.0 → 8.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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -4
  3. data/lib/ldclient-rb/config.rb +112 -62
  4. data/lib/ldclient-rb/context.rb +444 -0
  5. data/lib/ldclient-rb/evaluation_detail.rb +26 -22
  6. data/lib/ldclient-rb/events.rb +256 -146
  7. data/lib/ldclient-rb/flags_state.rb +26 -15
  8. data/lib/ldclient-rb/impl/big_segments.rb +18 -18
  9. data/lib/ldclient-rb/impl/broadcaster.rb +78 -0
  10. data/lib/ldclient-rb/impl/context.rb +96 -0
  11. data/lib/ldclient-rb/impl/context_filter.rb +145 -0
  12. data/lib/ldclient-rb/impl/data_source.rb +188 -0
  13. data/lib/ldclient-rb/impl/data_store.rb +59 -0
  14. data/lib/ldclient-rb/impl/dependency_tracker.rb +102 -0
  15. data/lib/ldclient-rb/impl/diagnostic_events.rb +9 -10
  16. data/lib/ldclient-rb/impl/evaluator.rb +386 -142
  17. data/lib/ldclient-rb/impl/evaluator_bucketing.rb +40 -41
  18. data/lib/ldclient-rb/impl/evaluator_helpers.rb +50 -0
  19. data/lib/ldclient-rb/impl/evaluator_operators.rb +26 -55
  20. data/lib/ldclient-rb/impl/event_sender.rb +7 -6
  21. data/lib/ldclient-rb/impl/event_summarizer.rb +68 -0
  22. data/lib/ldclient-rb/impl/event_types.rb +136 -0
  23. data/lib/ldclient-rb/impl/flag_tracker.rb +58 -0
  24. data/lib/ldclient-rb/impl/integrations/consul_impl.rb +19 -7
  25. data/lib/ldclient-rb/impl/integrations/dynamodb_impl.rb +38 -30
  26. data/lib/ldclient-rb/impl/integrations/file_data_source.rb +24 -11
  27. data/lib/ldclient-rb/impl/integrations/redis_impl.rb +109 -12
  28. data/lib/ldclient-rb/impl/migrations/migrator.rb +287 -0
  29. data/lib/ldclient-rb/impl/migrations/tracker.rb +136 -0
  30. data/lib/ldclient-rb/impl/model/clause.rb +45 -0
  31. data/lib/ldclient-rb/impl/model/feature_flag.rb +255 -0
  32. data/lib/ldclient-rb/impl/model/preprocessed_data.rb +64 -0
  33. data/lib/ldclient-rb/impl/model/segment.rb +132 -0
  34. data/lib/ldclient-rb/impl/model/serialization.rb +54 -44
  35. data/lib/ldclient-rb/impl/repeating_task.rb +3 -4
  36. data/lib/ldclient-rb/impl/sampler.rb +25 -0
  37. data/lib/ldclient-rb/impl/store_client_wrapper.rb +102 -8
  38. data/lib/ldclient-rb/impl/store_data_set_sorter.rb +2 -2
  39. data/lib/ldclient-rb/impl/unbounded_pool.rb +1 -1
  40. data/lib/ldclient-rb/impl/util.rb +59 -1
  41. data/lib/ldclient-rb/in_memory_store.rb +9 -2
  42. data/lib/ldclient-rb/integrations/consul.rb +2 -2
  43. data/lib/ldclient-rb/integrations/dynamodb.rb +2 -2
  44. data/lib/ldclient-rb/integrations/file_data.rb +4 -4
  45. data/lib/ldclient-rb/integrations/redis.rb +5 -5
  46. data/lib/ldclient-rb/integrations/test_data/flag_builder.rb +287 -62
  47. data/lib/ldclient-rb/integrations/test_data.rb +18 -14
  48. data/lib/ldclient-rb/integrations/util/store_wrapper.rb +20 -9
  49. data/lib/ldclient-rb/interfaces.rb +600 -14
  50. data/lib/ldclient-rb/ldclient.rb +314 -134
  51. data/lib/ldclient-rb/memoized_value.rb +1 -1
  52. data/lib/ldclient-rb/migrations.rb +230 -0
  53. data/lib/ldclient-rb/non_blocking_thread_pool.rb +1 -1
  54. data/lib/ldclient-rb/polling.rb +52 -6
  55. data/lib/ldclient-rb/reference.rb +274 -0
  56. data/lib/ldclient-rb/requestor.rb +9 -11
  57. data/lib/ldclient-rb/stream.rb +96 -34
  58. data/lib/ldclient-rb/util.rb +97 -14
  59. data/lib/ldclient-rb/version.rb +1 -1
  60. data/lib/ldclient-rb.rb +3 -4
  61. metadata +65 -23
  62. data/lib/ldclient-rb/event_summarizer.rb +0 -55
  63. data/lib/ldclient-rb/file_data_source.rb +0 -23
  64. data/lib/ldclient-rb/impl/event_factory.rb +0 -126
  65. data/lib/ldclient-rb/newrelic.rb +0 -17
  66. data/lib/ldclient-rb/redis_store.rb +0 -88
  67. data/lib/ldclient-rb/user_filter.rb +0 -52
@@ -17,7 +17,7 @@ module LaunchDarkly
17
17
  # @private
18
18
  KEY_PATHS = {
19
19
  FEATURES => "/flags/",
20
- SEGMENTS => "/segments/"
20
+ SEGMENTS => "/segments/",
21
21
  }
22
22
 
23
23
  # @private
@@ -25,6 +25,7 @@ module LaunchDarkly
25
25
  def initialize(sdk_key, config, diagnostic_accumulator = nil)
26
26
  @sdk_key = sdk_key
27
27
  @config = config
28
+ @data_source_update_sink = config.data_source_update_sink
28
29
  @feature_store = config.feature_store
29
30
  @initialized = Concurrent::AtomicBoolean.new(false)
30
31
  @started = Concurrent::AtomicBoolean.new(false)
@@ -41,77 +42,138 @@ module LaunchDarkly
41
42
  return @ready unless @started.make_true
42
43
 
43
44
  @config.logger.info { "[LDClient] Initializing stream connection" }
44
-
45
+
45
46
  headers = Impl::Util.default_http_headers(@sdk_key, @config)
46
47
  opts = {
47
48
  headers: headers,
48
49
  read_timeout: READ_TIMEOUT_SECONDS,
49
50
  logger: @config.logger,
50
- socket_factory: @config.socket_factory
51
+ socket_factory: @config.socket_factory,
52
+ reconnect_time: @config.initial_reconnect_delay,
51
53
  }
52
54
  log_connection_started
53
- @es = SSE::Client.new(@config.stream_uri + "/all", **opts) do |conn|
55
+
56
+ uri = Util.add_payload_filter_key(@config.stream_uri + "/all", @config)
57
+ @es = SSE::Client.new(uri, **opts) do |conn|
54
58
  conn.on_event { |event| process_message(event) }
55
59
  conn.on_error { |err|
56
60
  log_connection_result(false)
57
61
  case err
58
62
  when SSE::Errors::HTTPStatusError
59
63
  status = err.status
64
+ error_info = LaunchDarkly::Interfaces::DataSource::ErrorInfo.new(
65
+ LaunchDarkly::Interfaces::DataSource::ErrorInfo::ERROR_RESPONSE, status, nil, Time.now)
60
66
  message = Util.http_error_message(status, "streaming connection", "will retry")
61
67
  @config.logger.error { "[LDClient] #{message}" }
62
- if !Util.http_error_recoverable?(status)
68
+
69
+ if Util.http_error_recoverable?(status)
70
+ @data_source_update_sink&.update_status(
71
+ LaunchDarkly::Interfaces::DataSource::Status::INTERRUPTED,
72
+ error_info
73
+ )
74
+ else
63
75
  @ready.set # if client was waiting on us, make it stop waiting - has no effect if already set
64
- stop
76
+ stop_with_error_info error_info
65
77
  end
78
+ when SSE::Errors::HTTPContentTypeError, SSE::Errors::HTTPProxyError, SSE::Errors::ReadTimeoutError
79
+ @data_source_update_sink&.update_status(
80
+ LaunchDarkly::Interfaces::DataSource::Status::INTERRUPTED,
81
+ LaunchDarkly::Interfaces::DataSource::ErrorInfo.new(LaunchDarkly::Interfaces::DataSource::ErrorInfo::NETWORK_ERROR, 0, err.to_s, Time.now)
82
+ )
83
+
84
+ else
85
+ @data_source_update_sink&.update_status(
86
+ LaunchDarkly::Interfaces::DataSource::Status::INTERRUPTED,
87
+ LaunchDarkly::Interfaces::DataSource::ErrorInfo.new(LaunchDarkly::Interfaces::DataSource::ErrorInfo::UNKNOWN, 0, err.to_s, Time.now)
88
+ )
66
89
  end
67
90
  }
68
91
  end
69
-
92
+
70
93
  @ready
71
94
  end
72
95
 
73
96
  def stop
97
+ stop_with_error_info
98
+ end
99
+
100
+ private
101
+
102
+ #
103
+ # @param [LaunchDarkly::Interfaces::DataSource::ErrorInfo, nil] error_info
104
+ #
105
+ def stop_with_error_info(error_info = nil)
74
106
  if @stopped.make_true
75
107
  @es.close
108
+ @data_source_update_sink&.update_status(LaunchDarkly::Interfaces::DataSource::Status::OFF, error_info)
76
109
  @config.logger.info { "[LDClient] Stream connection stopped" }
77
110
  end
78
111
  end
79
112
 
80
- private
113
+ #
114
+ # The original implementation of this class relied on the feature store
115
+ # directly, which we are trying to move away from. Customers who might have
116
+ # instantiated this directly for some reason wouldn't know they have to set
117
+ # the config's sink manually, so we have to fall back to the store if the
118
+ # sink isn't present.
119
+ #
120
+ # The next major release should be able to simplify this structure and
121
+ # remove the need for fall back to the data store because the update sink
122
+ # should always be present.
123
+ #
124
+ def update_sink_or_data_store
125
+ @data_source_update_sink || @feature_store
126
+ end
81
127
 
82
128
  def process_message(message)
83
129
  log_connection_result(true)
84
130
  method = message.type
85
131
  @config.logger.debug { "[LDClient] Stream received #{method} message: #{message.data}" }
86
- if method == PUT
87
- message = JSON.parse(message.data, symbolize_names: true)
88
- all_data = Impl::Model.make_all_store_data(message[:data])
89
- @feature_store.init(all_data)
90
- @initialized.make_true
91
- @config.logger.info { "[LDClient] Stream initialized" }
92
- @ready.set
93
- elsif method == PATCH
94
- data = JSON.parse(message.data, symbolize_names: true)
95
- for kind in [FEATURES, SEGMENTS]
96
- key = key_for_path(kind, data[:path])
97
- if key
98
- data = data[:data]
99
- Impl::Model.postprocess_item_after_deserializing!(kind, data)
100
- @feature_store.upsert(kind, data)
101
- break
132
+
133
+ begin
134
+ if method == PUT
135
+ message = JSON.parse(message.data, symbolize_names: true)
136
+ all_data = Impl::Model.make_all_store_data(message[:data], @config.logger)
137
+ update_sink_or_data_store.init(all_data)
138
+ @initialized.make_true
139
+ @config.logger.info { "[LDClient] Stream initialized" }
140
+ @ready.set
141
+ elsif method == PATCH
142
+ data = JSON.parse(message.data, symbolize_names: true)
143
+ for kind in [FEATURES, SEGMENTS]
144
+ key = key_for_path(kind, data[:path])
145
+ if key
146
+ item = Impl::Model.deserialize(kind, data[:data], @config.logger)
147
+ update_sink_or_data_store.upsert(kind, item)
148
+ break
149
+ end
102
150
  end
103
- end
104
- elsif method == DELETE
105
- data = JSON.parse(message.data, symbolize_names: true)
106
- for kind in [FEATURES, SEGMENTS]
107
- key = key_for_path(kind, data[:path])
108
- if key
109
- @feature_store.delete(kind, key, data[:version])
110
- break
151
+ elsif method == DELETE
152
+ data = JSON.parse(message.data, symbolize_names: true)
153
+ for kind in [FEATURES, SEGMENTS]
154
+ key = key_for_path(kind, data[:path])
155
+ if key
156
+ update_sink_or_data_store.delete(kind, key, data[:version])
157
+ break
158
+ end
111
159
  end
160
+ else
161
+ @config.logger.warn { "[LDClient] Unknown message received: #{method}" }
112
162
  end
113
- else
114
- @config.logger.warn { "[LDClient] Unknown message received: #{method}" }
163
+
164
+ @data_source_update_sink&.update_status(LaunchDarkly::Interfaces::DataSource::Status::VALID, nil)
165
+ rescue JSON::ParserError => e
166
+ @config.logger.error { "[LDClient] JSON parsing failed for method #{method}. Ignoring event." }
167
+ error_info = LaunchDarkly::Interfaces::DataSource::ErrorInfo.new(
168
+ LaunchDarkly::Interfaces::DataSource::ErrorInfo::INVALID_DATA,
169
+ 0,
170
+ e.to_s,
171
+ Time.now
172
+ )
173
+ @data_source_update_sink&.update_status(LaunchDarkly::Interfaces::DataSource::Status::INTERRUPTED, error_info)
174
+
175
+ # Re-raise the exception so the SSE implementation can catch it and restart the stream.
176
+ raise
115
177
  end
116
178
  end
117
179
 
@@ -2,21 +2,95 @@ require "uri"
2
2
  require "http"
3
3
 
4
4
  module LaunchDarkly
5
+ #
6
+ # A Result is used to reflect the outcome of any operation.
7
+ #
8
+ # Results can either be considered a success or a failure.
9
+ #
10
+ # In the event of success, the Result will contain an option, nullable value to hold any success value back to the
11
+ # calling function.
12
+ #
13
+ # If the operation fails, the Result will contain an error describing the value.
14
+ #
15
+ class Result
16
+ #
17
+ # Create a successful result with the provided value.
18
+ #
19
+ # @param value [Object, nil]
20
+ # @return [Result]
21
+ #
22
+ def self.success(value)
23
+ Result.new(value)
24
+ end
25
+
26
+ #
27
+ # Create a failed result with the provided error description.
28
+ #
29
+ # @param error [String]
30
+ # @param exception [Exception, nil]
31
+ # @return [Result]
32
+ #
33
+ def self.fail(error, exception = nil)
34
+ Result.new(nil, error, exception)
35
+ end
36
+
37
+ #
38
+ # Was this result successful or did it encounter an error?
39
+ #
40
+ # @return [Boolean]
41
+ #
42
+ def success?
43
+ @error.nil?
44
+ end
45
+
46
+ #
47
+ # @return [Object, nil] The value returned from the operation if it was successful; nil otherwise.
48
+ #
49
+ attr_reader :value
50
+
51
+ #
52
+ # @return [String, nil] An error description of the failure; nil otherwise
53
+ #
54
+ attr_reader :error
55
+
56
+ #
57
+ # @return [Exception, nil] An optional exception which caused the failure
58
+ #
59
+ attr_reader :exception
60
+
61
+ private def initialize(value, error = nil, exception = nil)
62
+ @value = value
63
+ @error = error
64
+ @exception = exception
65
+ end
66
+ end
67
+
5
68
  # @private
6
69
  module Util
7
- def self.stringify_attrs(hash, attrs)
8
- return hash if hash.nil?
9
- ret = hash
10
- changed = false
11
- attrs.each do |attr|
12
- value = hash[attr]
13
- if !value.nil? && !value.is_a?(String)
14
- ret = hash.clone if !changed
15
- ret[attr] = value.to_s
16
- changed = true
17
- end
70
+ #
71
+ # Append the payload filter key query parameter to the provided URI.
72
+ #
73
+ # @param uri [String]
74
+ # @param config [Config]
75
+ # @return [String]
76
+ #
77
+ def self.add_payload_filter_key(uri, config)
78
+ return uri if config.payload_filter_key.nil?
79
+
80
+ unless config.payload_filter_key.is_a?(String) && !config.payload_filter_key.empty?
81
+ config.logger.warn { "[LDClient] Filter key must be a non-empty string. No filtering will be applied." }
82
+ return uri
83
+ end
84
+
85
+ begin
86
+ parsed = URI.parse(uri)
87
+ new_query_params = URI.decode_www_form(String(parsed.query)) << ["filter", config.payload_filter_key]
88
+ parsed.query = URI.encode_www_form(new_query_params)
89
+ parsed.to_s
90
+ rescue URI::InvalidURIError
91
+ config.logger.warn { "[LDClient] URI could not be parsed. No filtering will be applied." }
92
+ uri
18
93
  end
19
- ret
20
94
  end
21
95
 
22
96
  def self.new_http_client(uri_s, config)
@@ -24,10 +98,19 @@ module LaunchDarkly
24
98
  if config.socket_factory
25
99
  http_client_options["socket_class"] = config.socket_factory
26
100
  end
27
- return HTTP::Client.new(http_client_options)
101
+ proxy = URI.parse(uri_s).find_proxy
102
+ unless proxy.nil?
103
+ http_client_options["proxy"] = {
104
+ proxy_address: proxy.host,
105
+ proxy_port: proxy.port,
106
+ proxy_username: proxy.user,
107
+ proxy_password: proxy.password,
108
+ }
109
+ end
110
+ HTTP::Client.new(http_client_options)
28
111
  .timeout({
29
112
  read: config.read_timeout,
30
- connect: config.connect_timeout
113
+ connect: config.connect_timeout,
31
114
  })
32
115
  .persistent(uri_s)
33
116
  end
@@ -1,3 +1,3 @@
1
1
  module LaunchDarkly
2
- VERSION = "6.3.0"
2
+ VERSION = "8.0.0"
3
3
  end
data/lib/ldclient-rb.rb CHANGED
@@ -9,20 +9,19 @@ require "ldclient-rb/version"
9
9
  require "ldclient-rb/interfaces"
10
10
  require "ldclient-rb/util"
11
11
  require "ldclient-rb/flags_state"
12
+ require "ldclient-rb/migrations"
12
13
  require "ldclient-rb/ldclient"
13
14
  require "ldclient-rb/cache_store"
14
15
  require "ldclient-rb/expiring_cache"
15
16
  require "ldclient-rb/memoized_value"
16
17
  require "ldclient-rb/in_memory_store"
17
18
  require "ldclient-rb/config"
18
- require "ldclient-rb/newrelic"
19
+ require "ldclient-rb/context"
20
+ require "ldclient-rb/reference"
19
21
  require "ldclient-rb/stream"
20
22
  require "ldclient-rb/polling"
21
- require "ldclient-rb/user_filter"
22
23
  require "ldclient-rb/simple_lru_cache"
23
24
  require "ldclient-rb/non_blocking_thread_pool"
24
- require "ldclient-rb/event_summarizer"
25
25
  require "ldclient-rb/events"
26
26
  require "ldclient-rb/requestor"
27
- require "ldclient-rb/file_data_source"
28
27
  require "ldclient-rb/integrations"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: launchdarkly-server-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.3.0
4
+ version: 8.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - LaunchDarkly
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-09 00:00:00.000000000 Z
11
+ date: 2023-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-dynamodb
@@ -30,14 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 2.2.10
33
+ version: 2.2.33
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 2.2.10
40
+ version: 2.2.33
41
+ - !ruby/object:Gem::Dependency
42
+ name: simplecov
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.21'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.21'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rspec
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -58,42 +72,42 @@ dependencies:
58
72
  requirements:
59
73
  - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: 2.4.2
75
+ version: '2.6'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
- version: 2.4.2
82
+ version: '2.6'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: redis
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '4.2'
89
+ version: '5.0'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '4.2'
96
+ version: '5.0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: connection_pool
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: 2.2.3
103
+ version: '2.3'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: 2.2.3
110
+ version: '2.3'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: rspec_junit_formatter
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -151,19 +165,33 @@ dependencies:
151
165
  - !ruby/object:Gem::Version
152
166
  version: '1.7'
153
167
  - !ruby/object:Gem::Dependency
154
- name: oga
168
+ name: rubocop
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '1.37'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '1.37'
181
+ - !ruby/object:Gem::Dependency
182
+ name: rubocop-performance
155
183
  requirement: !ruby/object:Gem::Requirement
156
184
  requirements:
157
185
  - - "~>"
158
186
  - !ruby/object:Gem::Version
159
- version: '2.2'
187
+ version: '1.15'
160
188
  type: :development
161
189
  prerelease: false
162
190
  version_requirements: !ruby/object:Gem::Requirement
163
191
  requirements:
164
192
  - - "~>"
165
193
  - !ruby/object:Gem::Version
166
- version: '2.2'
194
+ version: '1.15'
167
195
  - !ruby/object:Gem::Dependency
168
196
  name: semantic
169
197
  requirement: !ruby/object:Gem::Requirement
@@ -198,14 +226,14 @@ dependencies:
198
226
  requirements:
199
227
  - - '='
200
228
  - !ruby/object:Gem::Version
201
- version: 2.1.1
229
+ version: 2.2.2
202
230
  type: :runtime
203
231
  prerelease: false
204
232
  version_requirements: !ruby/object:Gem::Requirement
205
233
  requirements:
206
234
  - - '='
207
235
  - !ruby/object:Gem::Version
208
- version: 2.1.1
236
+ version: 2.2.2
209
237
  - !ruby/object:Gem::Dependency
210
238
  name: json
211
239
  requirement: !ruby/object:Gem::Requirement
@@ -253,27 +281,42 @@ files:
253
281
  - lib/ldclient-rb.rb
254
282
  - lib/ldclient-rb/cache_store.rb
255
283
  - lib/ldclient-rb/config.rb
284
+ - lib/ldclient-rb/context.rb
256
285
  - lib/ldclient-rb/evaluation_detail.rb
257
- - lib/ldclient-rb/event_summarizer.rb
258
286
  - lib/ldclient-rb/events.rb
259
287
  - lib/ldclient-rb/expiring_cache.rb
260
- - lib/ldclient-rb/file_data_source.rb
261
288
  - lib/ldclient-rb/flags_state.rb
262
289
  - lib/ldclient-rb/impl.rb
263
290
  - lib/ldclient-rb/impl/big_segments.rb
291
+ - lib/ldclient-rb/impl/broadcaster.rb
292
+ - lib/ldclient-rb/impl/context.rb
293
+ - lib/ldclient-rb/impl/context_filter.rb
294
+ - lib/ldclient-rb/impl/data_source.rb
295
+ - lib/ldclient-rb/impl/data_store.rb
296
+ - lib/ldclient-rb/impl/dependency_tracker.rb
264
297
  - lib/ldclient-rb/impl/diagnostic_events.rb
265
298
  - lib/ldclient-rb/impl/evaluator.rb
266
299
  - lib/ldclient-rb/impl/evaluator_bucketing.rb
300
+ - lib/ldclient-rb/impl/evaluator_helpers.rb
267
301
  - lib/ldclient-rb/impl/evaluator_operators.rb
268
- - lib/ldclient-rb/impl/event_factory.rb
269
302
  - lib/ldclient-rb/impl/event_sender.rb
303
+ - lib/ldclient-rb/impl/event_summarizer.rb
304
+ - lib/ldclient-rb/impl/event_types.rb
305
+ - lib/ldclient-rb/impl/flag_tracker.rb
270
306
  - lib/ldclient-rb/impl/integrations/consul_impl.rb
271
307
  - lib/ldclient-rb/impl/integrations/dynamodb_impl.rb
272
308
  - lib/ldclient-rb/impl/integrations/file_data_source.rb
273
309
  - lib/ldclient-rb/impl/integrations/redis_impl.rb
274
310
  - lib/ldclient-rb/impl/integrations/test_data/test_data_source.rb
311
+ - lib/ldclient-rb/impl/migrations/migrator.rb
312
+ - lib/ldclient-rb/impl/migrations/tracker.rb
313
+ - lib/ldclient-rb/impl/model/clause.rb
314
+ - lib/ldclient-rb/impl/model/feature_flag.rb
315
+ - lib/ldclient-rb/impl/model/preprocessed_data.rb
316
+ - lib/ldclient-rb/impl/model/segment.rb
275
317
  - lib/ldclient-rb/impl/model/serialization.rb
276
318
  - lib/ldclient-rb/impl/repeating_task.rb
319
+ - lib/ldclient-rb/impl/sampler.rb
277
320
  - lib/ldclient-rb/impl/store_client_wrapper.rb
278
321
  - lib/ldclient-rb/impl/store_data_set_sorter.rb
279
322
  - lib/ldclient-rb/impl/unbounded_pool.rb
@@ -290,14 +333,13 @@ files:
290
333
  - lib/ldclient-rb/interfaces.rb
291
334
  - lib/ldclient-rb/ldclient.rb
292
335
  - lib/ldclient-rb/memoized_value.rb
293
- - lib/ldclient-rb/newrelic.rb
336
+ - lib/ldclient-rb/migrations.rb
294
337
  - lib/ldclient-rb/non_blocking_thread_pool.rb
295
338
  - lib/ldclient-rb/polling.rb
296
- - lib/ldclient-rb/redis_store.rb
339
+ - lib/ldclient-rb/reference.rb
297
340
  - lib/ldclient-rb/requestor.rb
298
341
  - lib/ldclient-rb/simple_lru_cache.rb
299
342
  - lib/ldclient-rb/stream.rb
300
- - lib/ldclient-rb/user_filter.rb
301
343
  - lib/ldclient-rb/util.rb
302
344
  - lib/ldclient-rb/version.rb
303
345
  homepage: https://github.com/launchdarkly/ruby-server-sdk
@@ -312,14 +354,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
312
354
  requirements:
313
355
  - - ">="
314
356
  - !ruby/object:Gem::Version
315
- version: 2.5.0
357
+ version: 3.0.0
316
358
  required_rubygems_version: !ruby/object:Gem::Requirement
317
359
  requirements:
318
360
  - - ">="
319
361
  - !ruby/object:Gem::Version
320
362
  version: '0'
321
363
  requirements: []
322
- rubygems_version: 3.2.33
364
+ rubygems_version: 3.4.21
323
365
  signing_key:
324
366
  specification_version: 4
325
367
  summary: LaunchDarkly SDK for Ruby
@@ -1,55 +0,0 @@
1
-
2
- module LaunchDarkly
3
- # @private
4
- EventSummary = Struct.new(:start_date, :end_date, :counters)
5
-
6
- # Manages the state of summarizable information for the EventProcessor, including the
7
- # event counters and user deduplication. Note that the methods of this class are
8
- # deliberately not thread-safe; the EventProcessor is responsible for enforcing
9
- # synchronization across both the summarizer and the event queue.
10
- #
11
- # @private
12
- class EventSummarizer
13
- def initialize
14
- clear
15
- end
16
-
17
- # Adds this event to our counters, if it is a type of event we need to count.
18
- def summarize_event(event)
19
- if event[:kind] == "feature"
20
- counter_key = {
21
- key: event[:key],
22
- version: event[:version],
23
- variation: event[:variation]
24
- }
25
- c = @counters[counter_key]
26
- if c.nil?
27
- @counters[counter_key] = {
28
- value: event[:value],
29
- default: event[:default],
30
- count: 1
31
- }
32
- else
33
- c[:count] = c[:count] + 1
34
- end
35
- time = event[:creationDate]
36
- if !time.nil?
37
- @start_date = time if @start_date == 0 || time < @start_date
38
- @end_date = time if time > @end_date
39
- end
40
- end
41
- end
42
-
43
- # Returns a snapshot of the current summarized event data, and resets this state.
44
- def snapshot
45
- ret = EventSummary.new(@start_date, @end_date, @counters)
46
- ret
47
- end
48
-
49
- def clear
50
- @start_date = 0
51
- @end_date = 0
52
- @counters = {}
53
- end
54
- end
55
- end
@@ -1,23 +0,0 @@
1
- require "ldclient-rb/integrations/file_data"
2
-
3
- module LaunchDarkly
4
- #
5
- # Deprecated entry point for the file data source feature.
6
- #
7
- # The new preferred usage is {LaunchDarkly::Integrations::FileData#data_source}.
8
- #
9
- # @deprecated This is replaced by {LaunchDarkly::Integrations::FileData}.
10
- #
11
- class FileDataSource
12
- #
13
- # Deprecated entry point for the file data source feature.
14
- #
15
- # The new preferred usage is {LaunchDarkly::Integrations::FileData#data_source}.
16
- #
17
- # @deprecated This is replaced by {LaunchDarkly::Integrations::FileData#data_source}.
18
- #
19
- def self.factory(options={})
20
- LaunchDarkly::Integrations::FileData.data_source(options)
21
- end
22
- end
23
- end