launchdarkly-server-sdk 8.17.0-java → 8.18.1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/ldclient-rb/impl/big_segments.rb +28 -7
- data/lib/ldclient-rb/impl/data_source/polling.rb +7 -4
- data/lib/ldclient-rb/impl/data_source/stream.rb +1 -0
- data/lib/ldclient-rb/impl/data_system/fdv2.rb +8 -5
- data/lib/ldclient-rb/impl/data_system/streaming.rb +1 -0
- data/lib/ldclient-rb/impl/integrations/consul_impl.rb +8 -6
- data/lib/ldclient-rb/impl/integrations/dynamodb_impl.rb +4 -1
- data/lib/ldclient-rb/impl/store_client_wrapper.rb +13 -7
- data/lib/ldclient-rb/ldclient.rb +10 -2
- data/lib/ldclient-rb/version.rb +1 -1
- metadata +10 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 978ab174d6d432ede341e1a970e140a06ae4c07e1a377202649233e779c85bec
|
|
4
|
+
data.tar.gz: ecca2bc7c0c0067c6c6b3b12b7cd018e0457eaa0d6ff694d65a5841d72bc3f5a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 52614f1147d38eaa8d2acf2fa2f4f72593a26520746bb3ed7ca8ccf5c1c13e29ef900b424e275e398867ad8590f30fb098bb40e8f51dab8bc5cac28bd8473935
|
|
7
|
+
data.tar.gz: e37a04e7d825571da84756b4b62dfb33132c2e4116101aad8cb8163a5e0cfaee8c89fb4f64fe9ab05a444724a5f5a135ba549de589e685c022056b82d867a54e
|
|
@@ -21,6 +21,7 @@ module LaunchDarkly
|
|
|
21
21
|
@status_provider = BigSegmentStoreStatusProviderImpl.new(-> { get_status })
|
|
22
22
|
@logger = logger
|
|
23
23
|
@last_status = nil
|
|
24
|
+
@poll_lock = Mutex.new
|
|
24
25
|
|
|
25
26
|
unless @store.nil?
|
|
26
27
|
@cache = ExpiringCache.new(big_segments_config.context_cache_size, big_segments_config.context_cache_time)
|
|
@@ -49,18 +50,41 @@ module LaunchDarkly
|
|
|
49
50
|
return BigSegmentMembershipResult.new(nil, BigSegmentsStatus::STORE_ERROR)
|
|
50
51
|
end
|
|
51
52
|
end
|
|
52
|
-
|
|
53
|
-
unless
|
|
53
|
+
status = get_status
|
|
54
|
+
unless status.available
|
|
54
55
|
return BigSegmentMembershipResult.new(membership, BigSegmentsStatus::STORE_ERROR)
|
|
55
56
|
end
|
|
56
|
-
BigSegmentMembershipResult.new(membership,
|
|
57
|
+
BigSegmentMembershipResult.new(membership, status.stale ? BigSegmentsStatus::STALE : BigSegmentsStatus::HEALTHY)
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
def get_status
|
|
60
|
-
@last_status
|
|
61
|
+
status = @last_status
|
|
62
|
+
return status if status
|
|
63
|
+
|
|
64
|
+
new_status = @poll_lock.synchronize do
|
|
65
|
+
# Another caller may have finished a poll while we waited for the lock.
|
|
66
|
+
status = @last_status
|
|
67
|
+
return status if status
|
|
68
|
+
|
|
69
|
+
query_store_status
|
|
70
|
+
end
|
|
71
|
+
@status_provider.update_status(new_status)
|
|
72
|
+
|
|
73
|
+
new_status
|
|
61
74
|
end
|
|
62
75
|
|
|
63
76
|
def poll_store_and_update_status
|
|
77
|
+
new_status = @poll_lock.synchronize { query_store_status }
|
|
78
|
+
@status_provider.update_status(new_status)
|
|
79
|
+
|
|
80
|
+
new_status
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#
|
|
84
|
+
# Queries the store and caches the result. Callers hold @poll_lock, so this must not notify
|
|
85
|
+
# observers - a listener that calls back into the manager would deadlock on the mutex.
|
|
86
|
+
#
|
|
87
|
+
private def query_store_status
|
|
64
88
|
new_status = Interfaces::BigSegmentStoreStatus.new(false, false) # default to "unavailable" if we don't get a new status below
|
|
65
89
|
unless @store.nil?
|
|
66
90
|
begin
|
|
@@ -71,9 +95,6 @@ module LaunchDarkly
|
|
|
71
95
|
end
|
|
72
96
|
end
|
|
73
97
|
@last_status = new_status
|
|
74
|
-
@status_provider.update_status(new_status)
|
|
75
|
-
|
|
76
|
-
new_status
|
|
77
98
|
end
|
|
78
99
|
|
|
79
100
|
def stale?(timestamp)
|
|
@@ -38,14 +38,17 @@ module LaunchDarkly
|
|
|
38
38
|
begin
|
|
39
39
|
all_data, headers = request_all_data
|
|
40
40
|
DataSource.record_environment_id(@config.data_source_update_sink, headers)
|
|
41
|
+
newly_initialized = false
|
|
41
42
|
if all_data
|
|
42
43
|
update_sink_or_data_store.init(all_data)
|
|
43
|
-
|
|
44
|
-
@config.logger.info { "[LDClient] Polling connection initialized" }
|
|
45
|
-
@ready.set
|
|
46
|
-
end
|
|
44
|
+
newly_initialized = @initialized.make_true
|
|
47
45
|
end
|
|
48
46
|
@config.data_source_update_sink&.update_status(LaunchDarkly::Interfaces::DataSource::Status::VALID, nil)
|
|
47
|
+
|
|
48
|
+
if newly_initialized
|
|
49
|
+
@config.logger.info { "[LDClient] Polling connection initialized" }
|
|
50
|
+
@ready.set
|
|
51
|
+
end
|
|
49
52
|
rescue JSON::ParserError => e
|
|
50
53
|
@config.logger.error { "[LDClient] JSON parsing failed for polling response." }
|
|
51
54
|
error_info = LaunchDarkly::Interfaces::DataSource::ErrorInfo.new(
|
|
@@ -292,6 +292,10 @@ module LaunchDarkly
|
|
|
292
292
|
|
|
293
293
|
# Set ready event if and only if a selector is defined for the changeset.
|
|
294
294
|
if basis.change_set.selector && basis.change_set.selector.defined?
|
|
295
|
+
@data_source_status_provider.update_status(
|
|
296
|
+
LaunchDarkly::Interfaces::DataSource::Status::VALID,
|
|
297
|
+
nil
|
|
298
|
+
)
|
|
295
299
|
@ready_event.set
|
|
296
300
|
return fallback
|
|
297
301
|
end
|
|
@@ -473,15 +477,14 @@ module LaunchDarkly
|
|
|
473
477
|
# Handle the update
|
|
474
478
|
@store.apply(update.change_set, true) if update.change_set
|
|
475
479
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
@ready_event.set
|
|
479
|
-
record_environment_id(update.environment_id)
|
|
480
|
-
end
|
|
480
|
+
valid = update.state == LaunchDarkly::Interfaces::DataSource::Status::VALID
|
|
481
|
+
record_environment_id(update.environment_id) if valid
|
|
481
482
|
|
|
482
483
|
# Update status
|
|
483
484
|
@data_source_status_provider.update_status(update.state, update.error)
|
|
484
485
|
|
|
486
|
+
@ready_event.set if valid
|
|
487
|
+
|
|
485
488
|
return SyncResult::FDV1 if update.fallback_to_fdv1
|
|
486
489
|
|
|
487
490
|
return SyncResult::REMOVE if update.state == LaunchDarkly::Interfaces::DataSource::Status::OFF
|
|
@@ -68,13 +68,15 @@ module LaunchDarkly
|
|
|
68
68
|
|
|
69
69
|
def get_all_internal(kind)
|
|
70
70
|
items_out = {}
|
|
71
|
-
|
|
72
|
-
(
|
|
71
|
+
prefix = kind_key(kind)
|
|
72
|
+
Diplomat::Kv.get_all(prefix, {}, :return).each do |result|
|
|
73
73
|
value = result[:value]
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
next if value.nil?
|
|
75
|
+
db_key = result[:key].to_s
|
|
76
|
+
next unless db_key.start_with?(prefix)
|
|
77
|
+
# Use the key that the item is stored under, not the key inside the item. A deleted
|
|
78
|
+
# item (a "tombstone") is not guaranteed to carry a key of its own.
|
|
79
|
+
items_out[db_key[prefix.length..].to_sym] = Model.deserialize(kind, value)
|
|
78
80
|
end
|
|
79
81
|
items_out
|
|
80
82
|
end
|
|
@@ -113,7 +113,10 @@ module LaunchDarkly
|
|
|
113
113
|
resp = @client.query(req)
|
|
114
114
|
resp.items.each do |item|
|
|
115
115
|
item_out = unmarshal_item(kind, item)
|
|
116
|
-
|
|
116
|
+
next if item_out.nil?
|
|
117
|
+
# Use the sort key that the item is stored under, not the key inside the item. A
|
|
118
|
+
# deleted item (a "tombstone") is not guaranteed to carry a key of its own.
|
|
119
|
+
items_out[item[SORT_KEY].to_sym] = item_out
|
|
117
120
|
end
|
|
118
121
|
break if resp.last_evaluated_key.nil? || resp.last_evaluated_key.length == 0
|
|
119
122
|
req.exclusive_start_key = resp.last_evaluated_key
|
|
@@ -23,6 +23,7 @@ module LaunchDarkly
|
|
|
23
23
|
|
|
24
24
|
@mutex = Mutex.new # Covers the following variables
|
|
25
25
|
@last_available = true
|
|
26
|
+
@stopped = false
|
|
26
27
|
# @type [LaunchDarkly::Impl::RepeatingTask, nil]
|
|
27
28
|
@poller = nil
|
|
28
29
|
end
|
|
@@ -53,12 +54,14 @@ module LaunchDarkly
|
|
|
53
54
|
|
|
54
55
|
def stop
|
|
55
56
|
@store.stop
|
|
56
|
-
@mutex.synchronize do
|
|
57
|
-
return if @poller.nil?
|
|
58
57
|
|
|
59
|
-
|
|
58
|
+
poller = @mutex.synchronize do
|
|
59
|
+
@stopped = true
|
|
60
|
+
task = @poller
|
|
60
61
|
@poller = nil
|
|
62
|
+
task
|
|
61
63
|
end
|
|
64
|
+
poller&.stop
|
|
62
65
|
end
|
|
63
66
|
|
|
64
67
|
def monitoring_enabled?
|
|
@@ -87,12 +90,12 @@ module LaunchDarkly
|
|
|
87
90
|
@store_update_sink.update_status(status)
|
|
88
91
|
|
|
89
92
|
if available
|
|
90
|
-
@mutex.synchronize do
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
@poller.stop
|
|
93
|
+
poller = @mutex.synchronize do
|
|
94
|
+
task = @poller
|
|
94
95
|
@poller = nil
|
|
96
|
+
task
|
|
95
97
|
end
|
|
98
|
+
poller&.stop
|
|
96
99
|
|
|
97
100
|
return
|
|
98
101
|
end
|
|
@@ -102,6 +105,9 @@ module LaunchDarkly
|
|
|
102
105
|
task = Impl::RepeatingTask.new(0.5, 0, -> { self.check_availability }, @logger, 'LD/StoreWrapper#check_availability')
|
|
103
106
|
|
|
104
107
|
@mutex.synchronize do
|
|
108
|
+
# A read can fail after stop, and a poller started then would never be stopped.
|
|
109
|
+
next if @stopped
|
|
110
|
+
|
|
105
111
|
@poller = task
|
|
106
112
|
@poller.start
|
|
107
113
|
end
|
data/lib/ldclient-rb/ldclient.rb
CHANGED
|
@@ -81,6 +81,10 @@ module LaunchDarkly
|
|
|
81
81
|
# The pid of the process in which the fork warning was last logged, or nil.
|
|
82
82
|
@fork_warned_pid = Concurrent::AtomicReference.new(nil)
|
|
83
83
|
|
|
84
|
+
# Each flag lets the matching cached-data warning log once per client.
|
|
85
|
+
@cached_data_evaluation_warned = Concurrent::AtomicBoolean.new(false)
|
|
86
|
+
@cached_data_all_flags_warned = Concurrent::AtomicBoolean.new(false)
|
|
87
|
+
|
|
84
88
|
start_up(wait_for_sec)
|
|
85
89
|
end
|
|
86
90
|
|
|
@@ -629,7 +633,9 @@ module LaunchDarkly
|
|
|
629
633
|
|
|
630
634
|
unless initialized?
|
|
631
635
|
if @data_system.store.initialized?
|
|
632
|
-
|
|
636
|
+
if @cached_data_all_flags_warned.make_true
|
|
637
|
+
@config.logger.warn { "Called all_flags_state before client initialization; using last known values from data store. This message is logged once." }
|
|
638
|
+
end
|
|
633
639
|
else
|
|
634
640
|
@config.logger.warn { "Called all_flags_state before client initialization. Data store not available; returning empty state" }
|
|
635
641
|
return FeatureFlagsState.new(false)
|
|
@@ -765,7 +771,9 @@ module LaunchDarkly
|
|
|
765
771
|
|
|
766
772
|
if @data_system.data_availability != Impl::DataSystem::DataAvailability::REFRESHED
|
|
767
773
|
if @data_system.data_availability == Impl::DataSystem::DataAvailability::CACHED
|
|
768
|
-
@
|
|
774
|
+
if @cached_data_evaluation_warned.make_true
|
|
775
|
+
@config.logger.warn { "[LDClient] Client has not finished initializing; using last known values from feature store. This message is logged once." }
|
|
776
|
+
end
|
|
769
777
|
else
|
|
770
778
|
@config.logger.error { "[LDClient] Client has not finished initializing; feature store unavailable, returning default value" }
|
|
771
779
|
detail = Evaluator.error_result(EvaluationReason::ERROR_CLIENT_NOT_READY, default)
|
data/lib/ldclient-rb/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: launchdarkly-server-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 8.
|
|
4
|
+
version: 8.18.1
|
|
5
5
|
platform: java
|
|
6
6
|
authors:
|
|
7
7
|
- LaunchDarkly
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-10-06 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: aws-sdk-dynamodb
|
|
@@ -331,16 +331,22 @@ dependencies:
|
|
|
331
331
|
name: json
|
|
332
332
|
requirement: !ruby/object:Gem::Requirement
|
|
333
333
|
requirements:
|
|
334
|
-
- - "
|
|
334
|
+
- - ">="
|
|
335
335
|
- !ruby/object:Gem::Version
|
|
336
336
|
version: '2.3'
|
|
337
|
+
- - "<"
|
|
338
|
+
- !ruby/object:Gem::Version
|
|
339
|
+
version: '4'
|
|
337
340
|
type: :runtime
|
|
338
341
|
prerelease: false
|
|
339
342
|
version_requirements: !ruby/object:Gem::Requirement
|
|
340
343
|
requirements:
|
|
341
|
-
- - "
|
|
344
|
+
- - ">="
|
|
342
345
|
- !ruby/object:Gem::Version
|
|
343
346
|
version: '2.3'
|
|
347
|
+
- - "<"
|
|
348
|
+
- !ruby/object:Gem::Version
|
|
349
|
+
version: '4'
|
|
344
350
|
description: Official LaunchDarkly SDK for Ruby
|
|
345
351
|
email:
|
|
346
352
|
- team@launchdarkly.com
|