launchdarkly-server-sdk 8.9.0 → 8.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71cc03d71aa917c1f2ac00b689bddfe0efddb535d3e7c2cd227ef0796f1a77bb
4
- data.tar.gz: 37380c38265a220fdf591a34671492e5a3fb9825f29959b3b46ed0b435a43654
3
+ metadata.gz: '093b2e9445507a3a8d7a2d237a62e7c65f2ecbcc32f5b878fa3cc1e31fd3809a'
4
+ data.tar.gz: '019cb6700f4d9a686bc5452c5a4e570db096de76c2c2e673a2c91545c771e0ba'
5
5
  SHA512:
6
- metadata.gz: 7e0263a677a3d559e9138384a2fcc7eee7651a59c59792104b17e7f9b34b4f169f9a77e71dd91cc03e23d48ce321bc1a8d60379f18a07b96f7c0550bdcfb5c6c
7
- data.tar.gz: 9fc01d2f4972879bb3ac598f59a82e3c0d4409d70fe32b2768eaa6acf554380311819244f435a2207eef34ba039bb49af5ab886967b93273827627613528d823
6
+ metadata.gz: 55ea3c36892ed86ffae6df71b21b62369ebe2dca57069ebddc088426f2579cb3178670baa6172b9bb1f61f0633221ca38b5470858344c9be339d2e4a84f14c4a
7
+ data.tar.gz: c06dcbedf9955b26ffd040ba5517d67b8722d863b42ce947cc42d99a293efc75d9a9bd55d046e3034c6f63ac7281c5e6a4e3592c42050ce4dbb91d18d7b0db16
data/README.md CHANGED
@@ -16,7 +16,7 @@ LaunchDarkly overview
16
16
  Supported Ruby versions
17
17
  -----------------------
18
18
 
19
- This version of the LaunchDarkly SDK has a minimum Ruby version of 2.5.0, or 9.2.0 for JRuby.
19
+ This version of the LaunchDarkly SDK has a minimum Ruby version of 3.0.0, or 9.3.0 for JRuby.
20
20
 
21
21
  Getting started
22
22
  -----------
@@ -81,6 +81,7 @@ module LaunchDarkly
81
81
  @hooks = (opts[:hooks] || []).keep_if { |hook| hook.is_a? Interfaces::Hooks::Hook }
82
82
  @omit_anonymous_contexts = opts.has_key?(:omit_anonymous_contexts) && opts[:omit_anonymous_contexts]
83
83
  @data_source_update_sink = nil
84
+ @instance_id = nil
84
85
  end
85
86
 
86
87
  #
@@ -97,6 +98,18 @@ module LaunchDarkly
97
98
  #
98
99
  attr_accessor :data_source_update_sink
99
100
 
101
+
102
+ #
103
+ # Returns the unique identifier for this instance of the SDK.
104
+ #
105
+ # This property should only be set by the SDK. Long term access of this
106
+ # property is not supported; it is temporarily being exposed to maintain
107
+ # backwards compatibility while the SDK structure is updated.
108
+ #
109
+ # @private
110
+ #
111
+ attr_accessor :instance_id
112
+
100
113
  #
101
114
  # The base URL for the LaunchDarkly server. This is configurable mainly for testing
102
115
  # purposes; most users should use the default value.
@@ -10,6 +10,7 @@ module LaunchDarkly
10
10
  class ConsulFeatureStoreCore
11
11
  begin
12
12
  require "diplomat"
13
+ require "ostruct"
13
14
  CONSUL_ENABLED = true
14
15
  rescue ScriptError, StandardError
15
16
  CONSUL_ENABLED = false
@@ -11,6 +11,9 @@ module LaunchDarkly
11
11
 
12
12
  def self.default_http_headers(sdk_key, config)
13
13
  ret = { "Authorization" => sdk_key, "User-Agent" => "RubyClient/" + LaunchDarkly::VERSION }
14
+
15
+ ret["X-LaunchDarkly-Instance-Id"] = config.instance_id unless config.instance_id.nil?
16
+
14
17
  if config.wrapper_name
15
18
  ret["X-LaunchDarkly-Wrapper"] = config.wrapper_name +
16
19
  (config.wrapper_version ? "/" + config.wrapper_version : "")
@@ -13,6 +13,7 @@ require "concurrent/atomics"
13
13
  require "digest/sha1"
14
14
  require "forwardable"
15
15
  require "logger"
16
+ require "securerandom"
16
17
  require "benchmark"
17
18
  require "json"
18
19
  require "openssl"
@@ -56,25 +57,57 @@ module LaunchDarkly
56
57
  end
57
58
 
58
59
  @sdk_key = sdk_key
59
- @hooks = Concurrent::Array.new(config.hooks)
60
+ config.instance_id = SecureRandom.uuid
61
+ @config = config
62
+
63
+ start_up(wait_for_sec)
64
+ end
65
+
66
+ #
67
+ # Re-initializes an existing client after a process fork.
68
+ #
69
+ # The SDK relies on multiple background threads to operate correctly. When a process forks, `these threads are not
70
+ # available to the child <https://apidock.com/ruby/Process/fork/class>`.
71
+ #
72
+ # As a result, the SDK will not function correctly in the child process until it is re-initialized.
73
+ #
74
+ # This method is effectively equivalent to instantiating a new client. Future iterations of the SDK will provide
75
+ # increasingly efficient re-initializing improvements.
76
+ #
77
+ # Note that any configuration provided to the SDK will need to survive the forking process independently. For this
78
+ # reason, it is recommended that any listener or hook integrations be added postfork unless you are certain it can
79
+ # survive the forking process.
80
+ #
81
+ # @param wait_for_sec [Float] maximum time (in seconds) to wait for initialization
82
+ #
83
+ def postfork(wait_for_sec = 5)
84
+ @data_source = nil
85
+ @event_processor = nil
86
+ @big_segment_store_manager = nil
87
+
88
+ start_up(wait_for_sec)
89
+ end
90
+
91
+ private def start_up(wait_for_sec)
92
+ @hooks = Concurrent::Array.new(@config.hooks)
60
93
 
61
94
  @shared_executor = Concurrent::SingleThreadExecutor.new
62
95
 
63
- data_store_broadcaster = LaunchDarkly::Impl::Broadcaster.new(@shared_executor, config.logger)
96
+ data_store_broadcaster = LaunchDarkly::Impl::Broadcaster.new(@shared_executor, @config.logger)
64
97
  store_sink = LaunchDarkly::Impl::DataStore::UpdateSink.new(data_store_broadcaster)
65
98
 
66
99
  # We need to wrap the feature store object with a FeatureStoreClientWrapper in order to add
67
100
  # some necessary logic around updates. Unfortunately, we have code elsewhere that accesses
68
101
  # the feature store through the Config object, so we need to make a new Config that uses
69
102
  # the wrapped store.
70
- @store = Impl::FeatureStoreClientWrapper.new(config.feature_store, store_sink, config.logger)
71
- updated_config = config.clone
103
+ @store = Impl::FeatureStoreClientWrapper.new(@config.feature_store, store_sink, @config.logger)
104
+ updated_config = @config.clone
72
105
  updated_config.instance_variable_set(:@feature_store, @store)
73
106
  @config = updated_config
74
107
 
75
108
  @data_store_status_provider = LaunchDarkly::Impl::DataStore::StatusProvider.new(@store, store_sink)
76
109
 
77
- @big_segment_store_manager = Impl::BigSegmentStoreManager.new(config.big_segments, @config.logger)
110
+ @big_segment_store_manager = Impl::BigSegmentStoreManager.new(@config.big_segments, @config.logger)
78
111
  @big_segment_store_status_provider = @big_segment_store_manager.status_provider
79
112
 
80
113
  get_flag = lambda { |key| @store.get(FEATURES, key) }
@@ -83,7 +116,7 @@ module LaunchDarkly
83
116
  @evaluator = LaunchDarkly::Impl::Evaluator.new(get_flag, get_segment, get_big_segments_membership, @config.logger)
84
117
 
85
118
  if !@config.offline? && @config.send_events && !@config.diagnostic_opt_out?
86
- diagnostic_accumulator = Impl::DiagnosticAccumulator.new(Impl::DiagnosticAccumulator.create_diagnostic_id(sdk_key))
119
+ diagnostic_accumulator = Impl::DiagnosticAccumulator.new(Impl::DiagnosticAccumulator.create_diagnostic_id(@sdk_key))
87
120
  else
88
121
  diagnostic_accumulator = nil
89
122
  end
@@ -91,7 +124,7 @@ module LaunchDarkly
91
124
  if @config.offline? || !@config.send_events
92
125
  @event_processor = NullEventProcessor.new
93
126
  else
94
- @event_processor = EventProcessor.new(sdk_key, config, nil, diagnostic_accumulator)
127
+ @event_processor = EventProcessor.new(@sdk_key, @config, nil, diagnostic_accumulator)
95
128
  end
96
129
 
97
130
  if @config.use_ldd?
@@ -115,9 +148,9 @@ module LaunchDarkly
115
148
  # Currently, data source factories take two parameters unless they need to be aware of diagnostic_accumulator, in
116
149
  # which case they take three parameters. This will be changed in the future to use a less awkware mechanism.
117
150
  if data_source_or_factory.arity == 3
118
- @data_source = data_source_or_factory.call(sdk_key, @config, diagnostic_accumulator)
151
+ @data_source = data_source_or_factory.call(@sdk_key, @config, diagnostic_accumulator)
119
152
  else
120
- @data_source = data_source_or_factory.call(sdk_key, @config)
153
+ @data_source = data_source_or_factory.call(@sdk_key, @config)
121
154
  end
122
155
  else
123
156
  @data_source = data_source_or_factory
@@ -1,3 +1,3 @@
1
1
  module LaunchDarkly
2
- VERSION = "8.9.0" # x-release-please-version
2
+ VERSION = "8.10.1" # x-release-please-version
3
3
  end
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: 8.9.0
4
+ version: 8.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - LaunchDarkly
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-13 00:00:00.000000000 Z
11
+ date: 2025-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-dynamodb
@@ -25,109 +25,115 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.57'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rexml
28
+ name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '3.3'
33
+ version: '2.2'
34
34
  - - ">="
35
35
  - !ruby/object:Gem::Version
36
- version: 3.3.7
36
+ version: 2.2.3
37
37
  type: :development
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
41
  - - "~>"
42
42
  - !ruby/object:Gem::Version
43
- version: '3.3'
43
+ version: '2.2'
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: 3.3.7
46
+ version: 2.2.3
47
47
  - !ruby/object:Gem::Dependency
48
- name: bundler
48
+ name: connection_pool
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - '='
51
+ - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: 2.2.33
53
+ version: '2.3'
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - '='
58
+ - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: 2.2.33
60
+ version: '2.3'
61
61
  - !ruby/object:Gem::Dependency
62
- name: simplecov
62
+ name: diplomat
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '0.21'
67
+ version: '2.6'
68
68
  type: :development
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: '0.21'
74
+ version: '2.6'
75
75
  - !ruby/object:Gem::Dependency
76
- name: rspec
76
+ name: listen
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: '3.10'
81
+ version: '3.3'
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: '3.10'
88
+ version: '3.3'
89
89
  - !ruby/object:Gem::Dependency
90
- name: diplomat
90
+ name: redis
91
91
  requirement: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: '2.6'
95
+ version: '5.0'
96
96
  type: :development
97
97
  prerelease: false
98
98
  version_requirements: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - "~>"
101
101
  - !ruby/object:Gem::Version
102
- version: '2.6'
102
+ version: '5.0'
103
103
  - !ruby/object:Gem::Dependency
104
- name: redis
104
+ name: rexml
105
105
  requirement: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - "~>"
108
108
  - !ruby/object:Gem::Version
109
- version: '5.0'
109
+ version: '3.3'
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: 3.3.7
110
113
  type: :development
111
114
  prerelease: false
112
115
  version_requirements: !ruby/object:Gem::Requirement
113
116
  requirements:
114
117
  - - "~>"
115
118
  - !ruby/object:Gem::Version
116
- version: '5.0'
119
+ version: '3.3'
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: 3.3.7
117
123
  - !ruby/object:Gem::Dependency
118
- name: connection_pool
124
+ name: rspec
119
125
  requirement: !ruby/object:Gem::Requirement
120
126
  requirements:
121
127
  - - "~>"
122
128
  - !ruby/object:Gem::Version
123
- version: '2.3'
129
+ version: '3.10'
124
130
  type: :development
125
131
  prerelease: false
126
132
  version_requirements: !ruby/object:Gem::Requirement
127
133
  requirements:
128
134
  - - "~>"
129
135
  - !ruby/object:Gem::Version
130
- version: '2.3'
136
+ version: '3.10'
131
137
  - !ruby/object:Gem::Dependency
132
138
  name: rspec_junit_formatter
133
139
  requirement: !ruby/object:Gem::Requirement
@@ -143,89 +149,95 @@ dependencies:
143
149
  - !ruby/object:Gem::Version
144
150
  version: '0.4'
145
151
  - !ruby/object:Gem::Dependency
146
- name: timecop
152
+ name: rubocop
147
153
  requirement: !ruby/object:Gem::Requirement
148
154
  requirements:
149
155
  - - "~>"
150
156
  - !ruby/object:Gem::Version
151
- version: '0.9'
157
+ version: '1.76'
152
158
  type: :development
153
159
  prerelease: false
154
160
  version_requirements: !ruby/object:Gem::Requirement
155
161
  requirements:
156
162
  - - "~>"
157
163
  - !ruby/object:Gem::Version
158
- version: '0.9'
164
+ version: '1.76'
159
165
  - !ruby/object:Gem::Dependency
160
- name: listen
166
+ name: rubocop-performance
161
167
  requirement: !ruby/object:Gem::Requirement
162
168
  requirements:
163
169
  - - "~>"
164
170
  - !ruby/object:Gem::Version
165
- version: '3.3'
171
+ version: '1.25'
166
172
  type: :development
167
173
  prerelease: false
168
174
  version_requirements: !ruby/object:Gem::Requirement
169
175
  requirements:
170
176
  - - "~>"
171
177
  - !ruby/object:Gem::Version
172
- version: '3.3'
178
+ version: '1.25'
173
179
  - !ruby/object:Gem::Dependency
174
- name: webrick
180
+ name: simplecov
175
181
  requirement: !ruby/object:Gem::Requirement
176
182
  requirements:
177
183
  - - "~>"
178
184
  - !ruby/object:Gem::Version
179
- version: '1.7'
185
+ version: '0.21'
180
186
  type: :development
181
187
  prerelease: false
182
188
  version_requirements: !ruby/object:Gem::Requirement
183
189
  requirements:
184
190
  - - "~>"
185
191
  - !ruby/object:Gem::Version
186
- version: '1.7'
192
+ version: '0.21'
187
193
  - !ruby/object:Gem::Dependency
188
- name: rubocop
194
+ name: timecop
189
195
  requirement: !ruby/object:Gem::Requirement
190
196
  requirements:
191
197
  - - "~>"
192
198
  - !ruby/object:Gem::Version
193
- version: '1.37'
199
+ version: '0.9'
194
200
  type: :development
195
201
  prerelease: false
196
202
  version_requirements: !ruby/object:Gem::Requirement
197
203
  requirements:
198
204
  - - "~>"
199
205
  - !ruby/object:Gem::Version
200
- version: '1.37'
206
+ version: '0.9'
201
207
  - !ruby/object:Gem::Dependency
202
- name: rubocop-performance
208
+ name: webrick
203
209
  requirement: !ruby/object:Gem::Requirement
204
210
  requirements:
205
211
  - - "~>"
206
212
  - !ruby/object:Gem::Version
207
- version: '1.15'
213
+ version: '1.7'
208
214
  type: :development
209
215
  prerelease: false
210
216
  version_requirements: !ruby/object:Gem::Requirement
211
217
  requirements:
212
218
  - - "~>"
213
219
  - !ruby/object:Gem::Version
214
- version: '1.15'
220
+ version: '1.7'
215
221
  - !ruby/object:Gem::Dependency
216
- name: semantic
222
+ name: benchmark
217
223
  requirement: !ruby/object:Gem::Requirement
218
224
  requirements:
219
225
  - - "~>"
220
226
  - !ruby/object:Gem::Version
221
- version: '1.6'
227
+ version: '0.1'
228
+ - - ">="
229
+ - !ruby/object:Gem::Version
230
+ version: 0.1.1
222
231
  type: :runtime
223
232
  prerelease: false
224
233
  version_requirements: !ruby/object:Gem::Requirement
225
234
  requirements:
226
235
  - - "~>"
227
236
  - !ruby/object:Gem::Version
228
- version: '1.6'
237
+ version: '0.1'
238
+ - - ">="
239
+ - !ruby/object:Gem::Version
240
+ version: 0.1.1
229
241
  - !ruby/object:Gem::Dependency
230
242
  name: concurrent-ruby
231
243
  requirement: !ruby/object:Gem::Requirement
@@ -269,33 +281,33 @@ dependencies:
269
281
  - !ruby/object:Gem::Version
270
282
  version: 0.1.2
271
283
  - !ruby/object:Gem::Dependency
272
- name: zlib
284
+ name: semantic
273
285
  requirement: !ruby/object:Gem::Requirement
274
286
  requirements:
275
287
  - - "~>"
276
288
  - !ruby/object:Gem::Version
277
- version: '3.1'
289
+ version: '1.6'
278
290
  type: :runtime
279
291
  prerelease: false
280
292
  version_requirements: !ruby/object:Gem::Requirement
281
293
  requirements:
282
294
  - - "~>"
283
295
  - !ruby/object:Gem::Version
284
- version: '3.1'
296
+ version: '1.6'
285
297
  - !ruby/object:Gem::Dependency
286
- name: json
298
+ name: zlib
287
299
  requirement: !ruby/object:Gem::Requirement
288
300
  requirements:
289
301
  - - "~>"
290
302
  - !ruby/object:Gem::Version
291
- version: '2.3'
303
+ version: '3.1'
292
304
  type: :runtime
293
305
  prerelease: false
294
306
  version_requirements: !ruby/object:Gem::Requirement
295
307
  requirements:
296
308
  - - "~>"
297
309
  - !ruby/object:Gem::Version
298
- version: '2.3'
310
+ version: '3.1'
299
311
  - !ruby/object:Gem::Dependency
300
312
  name: http
301
313
  requirement: !ruby/object:Gem::Requirement
@@ -316,6 +328,20 @@ dependencies:
316
328
  - - "<"
317
329
  - !ruby/object:Gem::Version
318
330
  version: 6.0.0
331
+ - !ruby/object:Gem::Dependency
332
+ name: json
333
+ requirement: !ruby/object:Gem::Requirement
334
+ requirements:
335
+ - - "~>"
336
+ - !ruby/object:Gem::Version
337
+ version: '2.3'
338
+ type: :runtime
339
+ prerelease: false
340
+ version_requirements: !ruby/object:Gem::Requirement
341
+ requirements:
342
+ - - "~>"
343
+ - !ruby/object:Gem::Version
344
+ version: '2.3'
319
345
  description: Official LaunchDarkly SDK for Ruby
320
346
  email:
321
347
  - team@launchdarkly.com