launchdarkly-server-sdk 6.2.5 → 6.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +0 -1
- data/lib/ldclient-rb/config.rb +95 -1
- data/lib/ldclient-rb/evaluation_detail.rb +67 -8
- data/lib/ldclient-rb/file_data_source.rb +9 -300
- data/lib/ldclient-rb/flags_state.rb +23 -12
- data/lib/ldclient-rb/impl/big_segments.rb +117 -0
- data/lib/ldclient-rb/impl/evaluator.rb +80 -28
- data/lib/ldclient-rb/impl/evaluator_operators.rb +1 -1
- data/lib/ldclient-rb/impl/event_factory.rb +9 -12
- data/lib/ldclient-rb/impl/integrations/dynamodb_impl.rb +82 -18
- data/lib/ldclient-rb/impl/integrations/file_data_source.rb +212 -0
- data/lib/ldclient-rb/impl/integrations/redis_impl.rb +84 -31
- data/lib/ldclient-rb/impl/integrations/test_data/test_data_source.rb +40 -0
- data/lib/ldclient-rb/impl/repeating_task.rb +47 -0
- data/lib/ldclient-rb/impl/util.rb +4 -1
- data/lib/ldclient-rb/integrations/consul.rb +8 -1
- data/lib/ldclient-rb/integrations/dynamodb.rb +47 -2
- data/lib/ldclient-rb/integrations/file_data.rb +108 -0
- data/lib/ldclient-rb/integrations/redis.rb +41 -1
- data/lib/ldclient-rb/integrations/test_data/flag_builder.rb +438 -0
- data/lib/ldclient-rb/integrations/test_data.rb +209 -0
- data/lib/ldclient-rb/integrations/util/store_wrapper.rb +5 -0
- data/lib/ldclient-rb/integrations.rb +2 -51
- data/lib/ldclient-rb/interfaces.rb +151 -1
- data/lib/ldclient-rb/ldclient.rb +43 -9
- data/lib/ldclient-rb/polling.rb +22 -41
- data/lib/ldclient-rb/stream.rb +2 -1
- data/lib/ldclient-rb/util.rb +10 -1
- data/lib/ldclient-rb/version.rb +1 -1
- metadata +14 -7
@@ -4,6 +4,11 @@ require "ldclient-rb/expiring_cache"
|
|
4
4
|
|
5
5
|
module LaunchDarkly
|
6
6
|
module Integrations
|
7
|
+
#
|
8
|
+
# Support code that may be helpful in creating integrations.
|
9
|
+
#
|
10
|
+
# @since 5.5.0
|
11
|
+
#
|
7
12
|
module Util
|
8
13
|
#
|
9
14
|
# CachingStoreWrapper is a partial implementation of the {LaunchDarkly::Interfaces::FeatureStore}
|
@@ -1,55 +1,6 @@
|
|
1
1
|
require "ldclient-rb/integrations/consul"
|
2
2
|
require "ldclient-rb/integrations/dynamodb"
|
3
|
+
require "ldclient-rb/integrations/file_data"
|
3
4
|
require "ldclient-rb/integrations/redis"
|
5
|
+
require "ldclient-rb/integrations/test_data"
|
4
6
|
require "ldclient-rb/integrations/util/store_wrapper"
|
5
|
-
|
6
|
-
module LaunchDarkly
|
7
|
-
#
|
8
|
-
# Tools for connecting the LaunchDarkly client to other software.
|
9
|
-
#
|
10
|
-
module Integrations
|
11
|
-
#
|
12
|
-
# Integration with [Consul](https://www.consul.io/).
|
13
|
-
#
|
14
|
-
# Note that in order to use this integration, you must first install the gem `diplomat`.
|
15
|
-
#
|
16
|
-
# @since 5.5.0
|
17
|
-
#
|
18
|
-
module Consul
|
19
|
-
# code is in ldclient-rb/impl/integrations/consul_impl
|
20
|
-
end
|
21
|
-
|
22
|
-
#
|
23
|
-
# Integration with [DynamoDB](https://aws.amazon.com/dynamodb/).
|
24
|
-
#
|
25
|
-
# Note that in order to use this integration, you must first install one of the AWS SDK gems: either
|
26
|
-
# `aws-sdk-dynamodb`, or the full `aws-sdk`.
|
27
|
-
#
|
28
|
-
# @since 5.5.0
|
29
|
-
#
|
30
|
-
module DynamoDB
|
31
|
-
# code is in ldclient-rb/impl/integrations/dynamodb_impl
|
32
|
-
end
|
33
|
-
|
34
|
-
#
|
35
|
-
# Integration with [Redis](https://redis.io/).
|
36
|
-
#
|
37
|
-
# Note that in order to use this integration, you must first install the `redis` and `connection-pool`
|
38
|
-
# gems.
|
39
|
-
#
|
40
|
-
# @since 5.5.0
|
41
|
-
#
|
42
|
-
module Redis
|
43
|
-
# code is in ldclient-rb/impl/integrations/redis_impl
|
44
|
-
end
|
45
|
-
|
46
|
-
#
|
47
|
-
# Support code that may be helpful in creating integrations.
|
48
|
-
#
|
49
|
-
# @since 5.5.0
|
50
|
-
#
|
51
|
-
module Util
|
52
|
-
# code is in ldclient-rb/integrations/util/
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require "observer"
|
1
2
|
|
2
3
|
module LaunchDarkly
|
3
4
|
#
|
@@ -120,7 +121,8 @@ module LaunchDarkly
|
|
120
121
|
#
|
121
122
|
# The client has its own standard implementation, which uses either a streaming connection or
|
122
123
|
# polling depending on your configuration. Normally you will not need to use another one
|
123
|
-
# except for testing purposes.
|
124
|
+
# except for testing purposes. Two such test fixtures are {LaunchDarkly::Integrations::FileData}
|
125
|
+
# and {LaunchDarkly::Integrations::TestData}.
|
124
126
|
#
|
125
127
|
module DataSource
|
126
128
|
#
|
@@ -149,5 +151,153 @@ module LaunchDarkly
|
|
149
151
|
def stop
|
150
152
|
end
|
151
153
|
end
|
154
|
+
|
155
|
+
module BigSegmentStore
|
156
|
+
#
|
157
|
+
# Returns information about the overall state of the store. This method will be called only
|
158
|
+
# when the SDK needs the latest state, so it should not be cached.
|
159
|
+
#
|
160
|
+
# @return [BigSegmentStoreMetadata]
|
161
|
+
#
|
162
|
+
def get_metadata
|
163
|
+
end
|
164
|
+
|
165
|
+
#
|
166
|
+
# Queries the store for a snapshot of the current segment state for a specific user.
|
167
|
+
#
|
168
|
+
# The user_hash is a base64-encoded string produced by hashing the user key as defined by
|
169
|
+
# the Big Segments specification; the store implementation does not need to know the details
|
170
|
+
# of how this is done, because it deals only with already-hashed keys, but the string can be
|
171
|
+
# assumed to only contain characters that are valid in base64.
|
172
|
+
#
|
173
|
+
# The return value should be either a Hash, or nil if the user is not referenced in any big
|
174
|
+
# segments. Each key in the Hash is a "segment reference", which is how segments are
|
175
|
+
# identified in Big Segment data. This string is not identical to the segment key-- the SDK
|
176
|
+
# will add other information. The store implementation should not be concerned with the
|
177
|
+
# format of the string. Each value in the Hash is true if the user is explicitly included in
|
178
|
+
# the segment, false if the user is explicitly excluded from the segment-- and is not also
|
179
|
+
# explicitly included (that is, if both an include and an exclude existed in the data, the
|
180
|
+
# include would take precedence). If the user's status in a particular segment is undefined,
|
181
|
+
# there should be no key or value for that segment.
|
182
|
+
#
|
183
|
+
# This Hash may be cached by the SDK, so it should not be modified after it is created. It
|
184
|
+
# is a snapshot of the segment membership state at one point in time.
|
185
|
+
#
|
186
|
+
# @param user_hash [String]
|
187
|
+
# @return [Hash] true/false values for Big Segments that reference this user
|
188
|
+
#
|
189
|
+
def get_membership(user_hash)
|
190
|
+
end
|
191
|
+
|
192
|
+
#
|
193
|
+
# Performs any necessary cleanup to shut down the store when the client is being shut down.
|
194
|
+
#
|
195
|
+
# @return [void]
|
196
|
+
#
|
197
|
+
def stop
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
#
|
202
|
+
# Values returned by {BigSegmentStore#get_metadata}.
|
203
|
+
#
|
204
|
+
class BigSegmentStoreMetadata
|
205
|
+
def initialize(last_up_to_date)
|
206
|
+
@last_up_to_date = last_up_to_date
|
207
|
+
end
|
208
|
+
|
209
|
+
# The Unix epoch millisecond timestamp of the last update to the {BigSegmentStore}. It is
|
210
|
+
# nil if the store has never been updated.
|
211
|
+
#
|
212
|
+
# @return [Integer|nil]
|
213
|
+
attr_reader :last_up_to_date
|
214
|
+
end
|
215
|
+
|
216
|
+
#
|
217
|
+
# Information about the status of a Big Segment store, provided by {BigSegmentStoreStatusProvider}.
|
218
|
+
#
|
219
|
+
# Big Segments are a specific type of user segments. For more information, read the LaunchDarkly
|
220
|
+
# documentation: https://docs.launchdarkly.com/home/users/big-segments
|
221
|
+
#
|
222
|
+
class BigSegmentStoreStatus
|
223
|
+
def initialize(available, stale)
|
224
|
+
@available = available
|
225
|
+
@stale = stale
|
226
|
+
end
|
227
|
+
|
228
|
+
# True if the Big Segment store is able to respond to queries, so that the SDK can evaluate
|
229
|
+
# whether a user is in a segment or not.
|
230
|
+
#
|
231
|
+
# If this property is false, the store is not able to make queries (for instance, it may not have
|
232
|
+
# a valid database connection). In this case, the SDK will treat any reference to a Big Segment
|
233
|
+
# as if no users are included in that segment. Also, the {EvaluationReason} associated with
|
234
|
+
# with any flag evaluation that references a Big Segment when the store is not available will
|
235
|
+
# have a `big_segments_status` of `STORE_ERROR`.
|
236
|
+
#
|
237
|
+
# @return [Boolean]
|
238
|
+
attr_reader :available
|
239
|
+
|
240
|
+
# True if the Big Segment store is available, but has not been updated within the amount of time
|
241
|
+
# specified by {BigSegmentsConfig#stale_after}.
|
242
|
+
#
|
243
|
+
# This may indicate that the LaunchDarkly Relay Proxy, which populates the store, has stopped
|
244
|
+
# running or has become unable to receive fresh data from LaunchDarkly. Any feature flag
|
245
|
+
# evaluations that reference a Big Segment will be using the last known data, which may be out
|
246
|
+
# of date. Also, the {EvaluationReason} associated with those evaluations will have a
|
247
|
+
# `big_segments_status` of `STALE`.
|
248
|
+
#
|
249
|
+
# @return [Boolean]
|
250
|
+
attr_reader :stale
|
251
|
+
|
252
|
+
def ==(other)
|
253
|
+
self.available == other.available && self.stale == other.stale
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
#
|
258
|
+
# An interface for querying the status of a Big Segment store.
|
259
|
+
#
|
260
|
+
# The Big Segment store is the component that receives information about Big Segments, normally
|
261
|
+
# from a database populated by the LaunchDarkly Relay Proxy. Big Segments are a specific type
|
262
|
+
# of user segments. For more information, read the LaunchDarkly documentation:
|
263
|
+
# https://docs.launchdarkly.com/home/users/big-segments
|
264
|
+
#
|
265
|
+
# An implementation of this interface is returned by {LDClient#big_segment_store_status_provider}.
|
266
|
+
# Application code never needs to implement this interface.
|
267
|
+
#
|
268
|
+
# There are two ways to interact with the status. One is to simply get the current status; if its
|
269
|
+
# `available` property is true, then the SDK is able to evaluate user membership in Big Segments,
|
270
|
+
# and the `stale`` property indicates whether the data might be out of date.
|
271
|
+
#
|
272
|
+
# The other way is to subscribe to status change notifications. Applications may wish to know if
|
273
|
+
# there is an outage in the Big Segment store, or if it has become stale (the Relay Proxy has
|
274
|
+
# stopped updating it with new data), since then flag evaluations that reference a Big Segment
|
275
|
+
# might return incorrect values. To allow finding out about status changes as soon as possible,
|
276
|
+
# `BigSegmentStoreStatusProvider` mixes in Ruby's
|
277
|
+
# [Observable](https://docs.ruby-lang.org/en/2.5.0/Observable.html) module to provide standard
|
278
|
+
# methods such as `add_observer`. Observers will be called with a new {BigSegmentStoreStatus}
|
279
|
+
# value whenever the status changes.
|
280
|
+
#
|
281
|
+
# @example Getting the current status
|
282
|
+
# status = client.big_segment_store_status_provider.status
|
283
|
+
#
|
284
|
+
# @example Subscribing to status notifications
|
285
|
+
# client.big_segment_store_status_provider.add_observer(self, :big_segments_status_changed)
|
286
|
+
#
|
287
|
+
# def big_segments_status_changed(new_status)
|
288
|
+
# puts "Big segment store status is now: #{new_status}"
|
289
|
+
# end
|
290
|
+
#
|
291
|
+
module BigSegmentStoreStatusProvider
|
292
|
+
include Observable
|
293
|
+
#
|
294
|
+
# Gets the current status of the store, if known.
|
295
|
+
#
|
296
|
+
# @return [BigSegmentStoreStatus] the status, or nil if the SDK has not yet queried the Big
|
297
|
+
# Segment store status
|
298
|
+
#
|
299
|
+
def status
|
300
|
+
end
|
301
|
+
end
|
152
302
|
end
|
153
303
|
end
|
data/lib/ldclient-rb/ldclient.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require "ldclient-rb/impl/big_segments"
|
1
2
|
require "ldclient-rb/impl/diagnostic_events"
|
2
3
|
require "ldclient-rb/impl/evaluator"
|
3
4
|
require "ldclient-rb/impl/event_factory"
|
@@ -57,9 +58,13 @@ module LaunchDarkly
|
|
57
58
|
updated_config.instance_variable_set(:@feature_store, @store)
|
58
59
|
@config = updated_config
|
59
60
|
|
61
|
+
@big_segment_store_manager = Impl::BigSegmentStoreManager.new(config.big_segments, @config.logger)
|
62
|
+
@big_segment_store_status_provider = @big_segment_store_manager.status_provider
|
63
|
+
|
60
64
|
get_flag = lambda { |key| @store.get(FEATURES, key) }
|
61
65
|
get_segment = lambda { |key| @store.get(SEGMENTS, key) }
|
62
|
-
|
66
|
+
get_big_segments_membership = lambda { |key| @big_segment_store_manager.get_user_membership(key) }
|
67
|
+
@evaluator = LaunchDarkly::Impl::Evaluator.new(get_flag, get_segment, get_big_segments_membership, @config.logger)
|
63
68
|
|
64
69
|
if !@config.offline? && @config.send_events && !@config.diagnostic_opt_out?
|
65
70
|
diagnostic_accumulator = Impl::DiagnosticAccumulator.new(Impl::DiagnosticAccumulator.create_diagnostic_id(sdk_key))
|
@@ -173,7 +178,7 @@ module LaunchDarkly
|
|
173
178
|
# Other supported user attributes include IP address, country code, and an arbitrary hash of
|
174
179
|
# custom attributes. For more about the supported user properties and how they work in
|
175
180
|
# LaunchDarkly, see [Targeting users](https://docs.launchdarkly.com/home/flags/targeting-users).
|
176
|
-
#
|
181
|
+
#
|
177
182
|
# The optional `:privateAttributeNames` user property allows you to specify a list of
|
178
183
|
# attribute names that should not be sent back to LaunchDarkly.
|
179
184
|
# [Private attributes](https://docs.launchdarkly.com/home/users/attributes#creating-private-user-attributes)
|
@@ -243,8 +248,8 @@ module LaunchDarkly
|
|
243
248
|
# @return [void]
|
244
249
|
#
|
245
250
|
def identify(user)
|
246
|
-
if !user || user[:key].nil?
|
247
|
-
@config.logger.warn("Identify called with nil user or
|
251
|
+
if !user || user[:key].nil? || user[:key].empty?
|
252
|
+
@config.logger.warn("Identify called with nil user or empty user key!")
|
248
253
|
return
|
249
254
|
end
|
250
255
|
sanitize_user(user)
|
@@ -333,6 +338,15 @@ module LaunchDarkly
|
|
333
338
|
def all_flags_state(user, options={})
|
334
339
|
return FeatureFlagsState.new(false) if @config.offline?
|
335
340
|
|
341
|
+
if !initialized?
|
342
|
+
if @store.initialized?
|
343
|
+
@config.logger.warn { "Called all_flags_state before client initialization; using last known values from data store" }
|
344
|
+
else
|
345
|
+
@config.logger.warn { "Called all_flags_state before client initialization. Data store not available; returning empty state" }
|
346
|
+
return FeatureFlagsState.new(false)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
336
350
|
unless user && !user[:key].nil?
|
337
351
|
@config.logger.error { "[LDClient] User and user key must be specified in all_flags_state" }
|
338
352
|
return FeatureFlagsState.new(false)
|
@@ -354,14 +368,25 @@ module LaunchDarkly
|
|
354
368
|
next
|
355
369
|
end
|
356
370
|
begin
|
357
|
-
|
358
|
-
state.add_flag(f, result.detail.value, result.detail.variation_index, with_reasons ? result.detail.reason : nil,
|
359
|
-
details_only_if_tracked)
|
371
|
+
detail = @evaluator.evaluate(f, user, @event_factory_default).detail
|
360
372
|
rescue => exn
|
373
|
+
detail = EvaluationDetail.new(nil, nil, EvaluationReason::error(EvaluationReason::ERROR_EXCEPTION))
|
361
374
|
Util.log_exception(@config.logger, "Error evaluating flag \"#{k}\" in all_flags_state", exn)
|
362
|
-
state.add_flag(f, nil, nil, with_reasons ? EvaluationReason::error(EvaluationReason::ERROR_EXCEPTION) : nil,
|
363
|
-
details_only_if_tracked)
|
364
375
|
end
|
376
|
+
|
377
|
+
requires_experiment_data = EventFactory.is_experiment(f, detail.reason)
|
378
|
+
flag_state = {
|
379
|
+
key: f[:key],
|
380
|
+
value: detail.value,
|
381
|
+
variation: detail.variation_index,
|
382
|
+
reason: detail.reason,
|
383
|
+
version: f[:version],
|
384
|
+
trackEvents: f[:trackEvents] || requires_experiment_data,
|
385
|
+
trackReason: requires_experiment_data,
|
386
|
+
debugEventsUntilDate: f[:debugEventsUntilDate],
|
387
|
+
}
|
388
|
+
|
389
|
+
state.add_flag(flag_state, with_reasons, details_only_if_tracked)
|
365
390
|
end
|
366
391
|
|
367
392
|
state
|
@@ -375,9 +400,18 @@ module LaunchDarkly
|
|
375
400
|
@config.logger.info { "[LDClient] Closing LaunchDarkly client..." }
|
376
401
|
@data_source.stop
|
377
402
|
@event_processor.stop
|
403
|
+
@big_segment_store_manager.stop
|
378
404
|
@store.stop
|
379
405
|
end
|
380
406
|
|
407
|
+
#
|
408
|
+
# Returns an interface for tracking the status of a Big Segment store.
|
409
|
+
#
|
410
|
+
# The {BigSegmentStoreStatusProvider} has methods for checking whether the Big Segment store
|
411
|
+
# is (as far as the SDK knows) currently operational and tracking changes in this status.
|
412
|
+
#
|
413
|
+
attr_reader :big_segment_store_status_provider
|
414
|
+
|
381
415
|
private
|
382
416
|
|
383
417
|
def create_default_data_source(sdk_key, config, diagnostic_accumulator)
|
data/lib/ldclient-rb/polling.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "ldclient-rb/impl/repeating_task"
|
2
|
+
|
1
3
|
require "concurrent/atomics"
|
2
4
|
require "thread"
|
3
5
|
|
@@ -9,8 +11,8 @@ module LaunchDarkly
|
|
9
11
|
@requestor = requestor
|
10
12
|
@initialized = Concurrent::AtomicBoolean.new(false)
|
11
13
|
@started = Concurrent::AtomicBoolean.new(false)
|
12
|
-
@stopped = Concurrent::AtomicBoolean.new(false)
|
13
14
|
@ready = Concurrent::Event.new
|
15
|
+
@task = Impl::RepeatingTask.new(@config.poll_interval, 0, -> { self.poll }, @config.logger)
|
14
16
|
end
|
15
17
|
|
16
18
|
def initialized?
|
@@ -20,56 +22,35 @@ module LaunchDarkly
|
|
20
22
|
def start
|
21
23
|
return @ready unless @started.make_true
|
22
24
|
@config.logger.info { "[LDClient] Initializing polling connection" }
|
23
|
-
|
25
|
+
@task.start
|
24
26
|
@ready
|
25
27
|
end
|
26
28
|
|
27
29
|
def stop
|
28
|
-
|
29
|
-
|
30
|
-
@worker.run # causes the thread to wake up if it's currently in a sleep
|
31
|
-
@worker.join
|
32
|
-
end
|
33
|
-
@config.logger.info { "[LDClient] Polling connection stopped" }
|
34
|
-
end
|
30
|
+
@task.stop
|
31
|
+
@config.logger.info { "[LDClient] Polling connection stopped" }
|
35
32
|
end
|
36
33
|
|
37
34
|
def poll
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
@
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def create_worker
|
49
|
-
@worker = Thread.new do
|
50
|
-
@config.logger.debug { "[LDClient] Starting polling worker" }
|
51
|
-
while !@stopped.value do
|
52
|
-
started_at = Time.now
|
53
|
-
begin
|
54
|
-
poll
|
55
|
-
rescue UnexpectedResponseError => e
|
56
|
-
message = Util.http_error_message(e.status, "polling request", "will retry")
|
57
|
-
@config.logger.error { "[LDClient] #{message}" };
|
58
|
-
if !Util.http_error_recoverable?(e.status)
|
59
|
-
@ready.set # if client was waiting on us, make it stop waiting - has no effect if already set
|
60
|
-
stop
|
61
|
-
end
|
62
|
-
rescue StandardError => exn
|
63
|
-
Util.log_exception(@config.logger, "Exception while polling", exn)
|
64
|
-
end
|
65
|
-
delta = @config.poll_interval - (Time.now - started_at)
|
66
|
-
if delta > 0
|
67
|
-
sleep(delta)
|
35
|
+
begin
|
36
|
+
all_data = @requestor.request_all_data
|
37
|
+
if all_data
|
38
|
+
@config.feature_store.init(all_data)
|
39
|
+
if @initialized.make_true
|
40
|
+
@config.logger.info { "[LDClient] Polling connection initialized" }
|
41
|
+
@ready.set
|
68
42
|
end
|
69
43
|
end
|
44
|
+
rescue UnexpectedResponseError => e
|
45
|
+
message = Util.http_error_message(e.status, "polling request", "will retry")
|
46
|
+
@config.logger.error { "[LDClient] #{message}" };
|
47
|
+
if !Util.http_error_recoverable?(e.status)
|
48
|
+
@ready.set # if client was waiting on us, make it stop waiting - has no effect if already set
|
49
|
+
stop
|
50
|
+
end
|
51
|
+
rescue StandardError => e
|
52
|
+
Util.log_exception(@config.logger, "Exception while polling", e)
|
70
53
|
end
|
71
54
|
end
|
72
|
-
|
73
|
-
private :poll, :create_worker
|
74
55
|
end
|
75
56
|
end
|
data/lib/ldclient-rb/stream.rb
CHANGED
@@ -47,7 +47,8 @@ module LaunchDarkly
|
|
47
47
|
headers: headers,
|
48
48
|
read_timeout: READ_TIMEOUT_SECONDS,
|
49
49
|
logger: @config.logger,
|
50
|
-
socket_factory: @config.socket_factory
|
50
|
+
socket_factory: @config.socket_factory,
|
51
|
+
reconnect_time: @config.initial_reconnect_delay
|
51
52
|
}
|
52
53
|
log_connection_started
|
53
54
|
@es = SSE::Client.new(@config.stream_uri + "/all", **opts) do |conn|
|
data/lib/ldclient-rb/util.rb
CHANGED
@@ -18,12 +18,21 @@ module LaunchDarkly
|
|
18
18
|
end
|
19
19
|
ret
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def self.new_http_client(uri_s, config)
|
23
23
|
http_client_options = {}
|
24
24
|
if config.socket_factory
|
25
25
|
http_client_options["socket_class"] = config.socket_factory
|
26
26
|
end
|
27
|
+
proxy = URI.parse(uri_s).find_proxy
|
28
|
+
if !proxy.nil?
|
29
|
+
http_client_options["proxy"] = {
|
30
|
+
proxy_address: proxy.host,
|
31
|
+
proxy_port: proxy.port,
|
32
|
+
proxy_username: proxy.user,
|
33
|
+
proxy_password: proxy.password
|
34
|
+
}
|
35
|
+
end
|
27
36
|
return HTTP::Client.new(http_client_options)
|
28
37
|
.timeout({
|
29
38
|
read: config.read_timeout,
|
data/lib/ldclient-rb/version.rb
CHANGED
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.2
|
4
|
+
version: 6.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- LaunchDarkly
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-dynamodb
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.2.
|
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.
|
40
|
+
version: 2.2.33
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -198,14 +198,14 @@ dependencies:
|
|
198
198
|
requirements:
|
199
199
|
- - '='
|
200
200
|
- !ruby/object:Gem::Version
|
201
|
-
version: 2.
|
201
|
+
version: 2.2.0
|
202
202
|
type: :runtime
|
203
203
|
prerelease: false
|
204
204
|
version_requirements: !ruby/object:Gem::Requirement
|
205
205
|
requirements:
|
206
206
|
- - '='
|
207
207
|
- !ruby/object:Gem::Version
|
208
|
-
version: 2.
|
208
|
+
version: 2.2.0
|
209
209
|
- !ruby/object:Gem::Dependency
|
210
210
|
name: json
|
211
211
|
requirement: !ruby/object:Gem::Requirement
|
@@ -260,6 +260,7 @@ files:
|
|
260
260
|
- lib/ldclient-rb/file_data_source.rb
|
261
261
|
- lib/ldclient-rb/flags_state.rb
|
262
262
|
- lib/ldclient-rb/impl.rb
|
263
|
+
- lib/ldclient-rb/impl/big_segments.rb
|
263
264
|
- lib/ldclient-rb/impl/diagnostic_events.rb
|
264
265
|
- lib/ldclient-rb/impl/evaluator.rb
|
265
266
|
- lib/ldclient-rb/impl/evaluator_bucketing.rb
|
@@ -268,8 +269,11 @@ files:
|
|
268
269
|
- lib/ldclient-rb/impl/event_sender.rb
|
269
270
|
- lib/ldclient-rb/impl/integrations/consul_impl.rb
|
270
271
|
- lib/ldclient-rb/impl/integrations/dynamodb_impl.rb
|
272
|
+
- lib/ldclient-rb/impl/integrations/file_data_source.rb
|
271
273
|
- lib/ldclient-rb/impl/integrations/redis_impl.rb
|
274
|
+
- lib/ldclient-rb/impl/integrations/test_data/test_data_source.rb
|
272
275
|
- lib/ldclient-rb/impl/model/serialization.rb
|
276
|
+
- lib/ldclient-rb/impl/repeating_task.rb
|
273
277
|
- lib/ldclient-rb/impl/store_client_wrapper.rb
|
274
278
|
- lib/ldclient-rb/impl/store_data_set_sorter.rb
|
275
279
|
- lib/ldclient-rb/impl/unbounded_pool.rb
|
@@ -278,7 +282,10 @@ files:
|
|
278
282
|
- lib/ldclient-rb/integrations.rb
|
279
283
|
- lib/ldclient-rb/integrations/consul.rb
|
280
284
|
- lib/ldclient-rb/integrations/dynamodb.rb
|
285
|
+
- lib/ldclient-rb/integrations/file_data.rb
|
281
286
|
- lib/ldclient-rb/integrations/redis.rb
|
287
|
+
- lib/ldclient-rb/integrations/test_data.rb
|
288
|
+
- lib/ldclient-rb/integrations/test_data/flag_builder.rb
|
282
289
|
- lib/ldclient-rb/integrations/util/store_wrapper.rb
|
283
290
|
- lib/ldclient-rb/interfaces.rb
|
284
291
|
- lib/ldclient-rb/ldclient.rb
|
@@ -312,7 +319,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
312
319
|
- !ruby/object:Gem::Version
|
313
320
|
version: '0'
|
314
321
|
requirements: []
|
315
|
-
rubygems_version: 3.
|
322
|
+
rubygems_version: 3.3.9
|
316
323
|
signing_key:
|
317
324
|
specification_version: 4
|
318
325
|
summary: LaunchDarkly SDK for Ruby
|