launchdarkly-server-sdk 8.13.0-java → 8.15.0-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/README.md +1 -1
- data/lib/ldclient-rb/config.rb +24 -3
- data/lib/ldclient-rb/data_system/polling_data_source_builder.rb +7 -5
- data/lib/ldclient-rb/impl/context_filter.rb +7 -7
- data/lib/ldclient-rb/impl/data_source/polling.rb +14 -1
- data/lib/ldclient-rb/impl/data_source/requestor.rb +13 -3
- data/lib/ldclient-rb/impl/data_source/stream.rb +2 -0
- data/lib/ldclient-rb/impl/data_source.rb +37 -0
- data/lib/ldclient-rb/impl/data_store/feature_store_client_wrapper.rb +12 -0
- data/lib/ldclient-rb/impl/data_store/store.rb +24 -0
- data/lib/ldclient-rb/impl/data_system/fdv1.rb +5 -0
- data/lib/ldclient-rb/impl/data_system/fdv2.rb +92 -13
- data/lib/ldclient-rb/impl/data_system/polling.rb +100 -33
- data/lib/ldclient-rb/impl/data_system/protocolv2.rb +3 -29
- data/lib/ldclient-rb/impl/data_system/streaming.rb +54 -31
- data/lib/ldclient-rb/impl/data_system.rb +15 -5
- data/lib/ldclient-rb/impl/integrations/file_data_source_v2.rb +29 -22
- data/lib/ldclient-rb/impl/integrations/redis_impl.rb +4 -0
- data/lib/ldclient-rb/impl/integrations/test_data/test_data_source_v2.rb +53 -48
- data/lib/ldclient-rb/integrations/consul.rb +6 -2
- data/lib/ldclient-rb/integrations/dynamodb.rb +6 -2
- data/lib/ldclient-rb/integrations/file_data.rb +1 -4
- data/lib/ldclient-rb/integrations/redis.rb +6 -2
- data/lib/ldclient-rb/integrations/test_data_v2.rb +0 -3
- data/lib/ldclient-rb/integrations/util/store_wrapper.rb +39 -19
- data/lib/ldclient-rb/interfaces/data_system.rb +60 -57
- data/lib/ldclient-rb/interfaces/hooks.rb +11 -1
- data/lib/ldclient-rb/ldclient.rb +1 -1
- data/lib/ldclient-rb/util.rb +3 -2
- data/lib/ldclient-rb/version.rb +1 -1
- metadata +2 -2
|
@@ -46,56 +46,61 @@ module LaunchDarkly
|
|
|
46
46
|
# Implementation of the Initializer.fetch method.
|
|
47
47
|
#
|
|
48
48
|
# Returns the current test data as a Basis for initial data loading.
|
|
49
|
+
# Test data sources never request the FDv1 Fallback Directive, so the
|
|
50
|
+
# returned {FetchResult} always reports `fallback_to_fdv1: false`.
|
|
49
51
|
#
|
|
50
52
|
# @param selector_store [LaunchDarkly::Interfaces::DataSystem::SelectorStore] Provides the Selector (unused for test data)
|
|
51
|
-
# @return [LaunchDarkly::
|
|
53
|
+
# @return [LaunchDarkly::Interfaces::DataSystem::FetchResult]
|
|
52
54
|
#
|
|
53
55
|
def fetch(selector_store)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
56
|
+
result =
|
|
57
|
+
begin
|
|
58
|
+
@lock.synchronize do
|
|
59
|
+
if @closed
|
|
60
|
+
next LaunchDarkly::Result.fail('TestDataV2 source has been closed')
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Get all current flags and segments from test data
|
|
64
|
+
init_data = @test_data.make_init_data
|
|
65
|
+
version = @test_data.get_version
|
|
66
|
+
|
|
67
|
+
# Build a full transfer changeset
|
|
68
|
+
builder = LaunchDarkly::Interfaces::DataSystem::ChangeSetBuilder.new
|
|
69
|
+
builder.start(LaunchDarkly::Interfaces::DataSystem::IntentCode::TRANSFER_FULL)
|
|
70
|
+
|
|
71
|
+
# Add all flags to the changeset
|
|
72
|
+
init_data[:flags].each do |key, flag_data|
|
|
73
|
+
builder.add_put(
|
|
74
|
+
LaunchDarkly::Interfaces::DataSystem::ObjectKind::FLAG,
|
|
75
|
+
key,
|
|
76
|
+
flag_data[:version] || 1,
|
|
77
|
+
flag_data
|
|
78
|
+
)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Add all segments to the changeset
|
|
82
|
+
init_data[:segments].each do |key, segment_data|
|
|
83
|
+
builder.add_put(
|
|
84
|
+
LaunchDarkly::Interfaces::DataSystem::ObjectKind::SEGMENT,
|
|
85
|
+
key,
|
|
86
|
+
segment_data[:version] || 1,
|
|
87
|
+
segment_data
|
|
88
|
+
)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Create selector for this version
|
|
92
|
+
selector = LaunchDarkly::Interfaces::DataSystem::Selector.new_selector(version.to_s, version)
|
|
93
|
+
change_set = builder.finish(selector)
|
|
94
|
+
|
|
95
|
+
basis = LaunchDarkly::Interfaces::DataSystem::Basis.new(change_set: change_set, persist: false, environment_id: nil)
|
|
96
|
+
|
|
97
|
+
LaunchDarkly::Result.success(basis)
|
|
86
98
|
end
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
selector = LaunchDarkly::Interfaces::DataSystem::Selector.new_selector(version.to_s, version)
|
|
90
|
-
change_set = builder.finish(selector)
|
|
91
|
-
|
|
92
|
-
basis = LaunchDarkly::Interfaces::DataSystem::Basis.new(change_set: change_set, persist: false, environment_id: nil)
|
|
93
|
-
|
|
94
|
-
LaunchDarkly::Result.success(basis)
|
|
99
|
+
rescue => e
|
|
100
|
+
LaunchDarkly::Result.fail("Error fetching test data: #{e.message}", e)
|
|
95
101
|
end
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
end
|
|
102
|
+
|
|
103
|
+
LaunchDarkly::Interfaces::DataSystem::FetchResult.new(result: result, fallback_to_fdv1: false)
|
|
99
104
|
end
|
|
100
105
|
|
|
101
106
|
#
|
|
@@ -109,14 +114,14 @@ module LaunchDarkly
|
|
|
109
114
|
#
|
|
110
115
|
def sync(selector_store)
|
|
111
116
|
# First yield initial data
|
|
112
|
-
|
|
113
|
-
unless
|
|
117
|
+
initial_fetch = fetch(selector_store)
|
|
118
|
+
unless initial_fetch.success?
|
|
114
119
|
yield LaunchDarkly::Interfaces::DataSystem::Update.new(
|
|
115
120
|
state: LaunchDarkly::Interfaces::DataSource::Status::OFF,
|
|
116
121
|
error: LaunchDarkly::Interfaces::DataSource::ErrorInfo.new(
|
|
117
122
|
LaunchDarkly::Interfaces::DataSource::ErrorInfo::STORE_ERROR,
|
|
118
123
|
0,
|
|
119
|
-
|
|
124
|
+
initial_fetch.error,
|
|
120
125
|
Time.now
|
|
121
126
|
)
|
|
122
127
|
)
|
|
@@ -126,7 +131,7 @@ module LaunchDarkly
|
|
|
126
131
|
# Yield the initial successful state
|
|
127
132
|
yield LaunchDarkly::Interfaces::DataSystem::Update.new(
|
|
128
133
|
state: LaunchDarkly::Interfaces::DataSource::Status::VALID,
|
|
129
|
-
change_set:
|
|
134
|
+
change_set: initial_fetch.value.change_set
|
|
130
135
|
)
|
|
131
136
|
|
|
132
137
|
# Continue yielding updates as they arrive
|
|
@@ -32,8 +32,12 @@ module LaunchDarkly
|
|
|
32
32
|
# @option opts [String] :url shortcut for setting the `url` property of the Consul client configuration
|
|
33
33
|
# @option opts [String] :prefix namespace prefix to add to all keys used by LaunchDarkly
|
|
34
34
|
# @option opts [Logger] :logger a `Logger` instance; defaults to `Config.default_logger`
|
|
35
|
-
# @option opts [Integer] :expiration (15) expiration time for the in-memory cache, in seconds; 0 for no local caching
|
|
36
|
-
#
|
|
35
|
+
# @option opts [Integer] :expiration (15) expiration time for the in-memory cache, in seconds; 0 for no local caching.
|
|
36
|
+
# When the SDK is configured to use FDv2, the persistent-store cache is automatically
|
|
37
|
+
# dropped once the in-memory store has been initialized, so this setting only affects
|
|
38
|
+
# the brief bootstrap window before the first set of flag data has been received.
|
|
39
|
+
# @option opts [Integer] :capacity (1000) maximum number of items in the cache.
|
|
40
|
+
# Same FDv2 caveat as `:expiration` applies.
|
|
37
41
|
# @return [LaunchDarkly::Interfaces::FeatureStore] a feature store object
|
|
38
42
|
#
|
|
39
43
|
def self.new_feature_store(opts = {})
|
|
@@ -42,8 +42,12 @@ module LaunchDarkly
|
|
|
42
42
|
# @option opts [Object] :existing_client an already-constructed DynamoDB client for the feature store to use
|
|
43
43
|
# @option opts [String] :prefix namespace prefix to add to all keys used by LaunchDarkly
|
|
44
44
|
# @option opts [Logger] :logger a `Logger` instance; defaults to `Config.default_logger`
|
|
45
|
-
# @option opts [Integer] :expiration (15) expiration time for the in-memory cache, in seconds; 0 for no local caching
|
|
46
|
-
#
|
|
45
|
+
# @option opts [Integer] :expiration (15) expiration time for the in-memory cache, in seconds; 0 for no local caching.
|
|
46
|
+
# When the SDK is configured to use FDv2, the persistent-store cache is automatically
|
|
47
|
+
# dropped once the in-memory store has been initialized, so this setting only affects
|
|
48
|
+
# the brief bootstrap window before the first set of flag data has been received.
|
|
49
|
+
# @option opts [Integer] :capacity (1000) maximum number of items in the cache.
|
|
50
|
+
# Same FDv2 caveat as `:expiration` applies.
|
|
47
51
|
# @return [LaunchDarkly::Interfaces::FeatureStore] a feature store object
|
|
48
52
|
#
|
|
49
53
|
def self.new_feature_store(table_name, opts = {})
|
|
@@ -50,7 +50,7 @@ module LaunchDarkly
|
|
|
50
50
|
# "segments": {
|
|
51
51
|
# "segment-key-1": {
|
|
52
52
|
# "key": "segment-key-1",
|
|
53
|
-
# "
|
|
53
|
+
# "included": [ "user-key-1" ]
|
|
54
54
|
# }
|
|
55
55
|
# }
|
|
56
56
|
# }
|
|
@@ -108,9 +108,6 @@ module LaunchDarkly
|
|
|
108
108
|
#
|
|
109
109
|
# Returns a builder for the FDv2-compatible file data source.
|
|
110
110
|
#
|
|
111
|
-
# This method is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
112
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
113
|
-
#
|
|
114
111
|
# This method returns a builder proc that can be used with the FDv2 data system
|
|
115
112
|
# configuration as both an Initializer and a Synchronizer. When used as an Initializer
|
|
116
113
|
# (via `fetch`), it reads files once. When used as a Synchronizer (via `sync`), it
|
|
@@ -50,8 +50,12 @@ module LaunchDarkly
|
|
|
50
50
|
# @option opts [String] :prefix (default_prefix) namespace prefix to add to all hash keys used by LaunchDarkly
|
|
51
51
|
# @option opts [Logger] :logger a `Logger` instance; defaults to `Config.default_logger`
|
|
52
52
|
# @option opts [Integer] :max_connections size of the Redis connection pool
|
|
53
|
-
# @option opts [Integer] :expiration (15) expiration time for the in-memory cache, in seconds; 0 for no local caching
|
|
54
|
-
#
|
|
53
|
+
# @option opts [Integer] :expiration (15) expiration time for the in-memory cache, in seconds; 0 for no local caching.
|
|
54
|
+
# When the SDK is configured to use FDv2, the persistent-store cache is automatically
|
|
55
|
+
# dropped once the in-memory store has been initialized, so this setting only affects
|
|
56
|
+
# the brief bootstrap window before the first set of flag data has been received.
|
|
57
|
+
# @option opts [Integer] :capacity (1000) maximum number of items in the cache.
|
|
58
|
+
# Same FDv2 caveat as `:expiration` applies.
|
|
55
59
|
# @option opts [Object] :pool custom connection pool, if desired
|
|
56
60
|
# @option opts [Boolean] :pool_shutdown_on_close whether calling `close` should shutdown the custom connection pool;
|
|
57
61
|
# this is true by default, and should be set to false only if you are managing the pool yourself and want its
|
|
@@ -9,9 +9,6 @@ module LaunchDarkly
|
|
|
9
9
|
# A mechanism for providing dynamically updatable feature flag state in a
|
|
10
10
|
# simplified form to an SDK client in test scenarios using the FDv2 protocol.
|
|
11
11
|
#
|
|
12
|
-
# This class is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
13
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
14
|
-
#
|
|
15
12
|
# Unlike {LaunchDarkly::Integrations::FileData}, this mechanism does not use any external resources. It
|
|
16
13
|
# provides only the data that the application has put into it using the {#update} method.
|
|
17
14
|
#
|
|
@@ -61,50 +61,52 @@ module LaunchDarkly
|
|
|
61
61
|
@core.init_internal(all_data)
|
|
62
62
|
@inited.make_true
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
cache = @cache
|
|
65
|
+
unless cache.nil?
|
|
66
|
+
cache.clear
|
|
66
67
|
all_data.each do |kind, items|
|
|
67
|
-
|
|
68
|
+
cache[kind] = items_if_not_deleted(items)
|
|
68
69
|
items.each do |key, item|
|
|
69
|
-
|
|
70
|
+
cache[item_cache_key(kind, key)] = [item]
|
|
70
71
|
end
|
|
71
72
|
end
|
|
72
73
|
end
|
|
73
74
|
end
|
|
74
75
|
|
|
75
76
|
def get(kind, key)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
cache = @cache
|
|
78
|
+
cache_key = item_cache_key(kind, key)
|
|
79
|
+
unless cache.nil?
|
|
80
|
+
cached = cache[cache_key] # note, item entries in the cache are wrapped in an array so we can cache nil values
|
|
79
81
|
return item_if_not_deleted(cached[0]) unless cached.nil?
|
|
80
82
|
end
|
|
81
83
|
|
|
82
84
|
item = @core.get_internal(kind, key)
|
|
83
85
|
|
|
84
|
-
unless
|
|
85
|
-
@cache[cache_key] = [item]
|
|
86
|
-
end
|
|
86
|
+
cache[cache_key] = [item] unless cache.nil?
|
|
87
87
|
|
|
88
88
|
item_if_not_deleted(item)
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
def all(kind)
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
cache = @cache
|
|
93
|
+
unless cache.nil?
|
|
94
|
+
items = cache[all_cache_key(kind)]
|
|
94
95
|
return items unless items.nil?
|
|
95
96
|
end
|
|
96
97
|
|
|
97
98
|
items = items_if_not_deleted(@core.get_all_internal(kind))
|
|
98
|
-
|
|
99
|
+
cache[all_cache_key(kind)] = items unless cache.nil?
|
|
99
100
|
items
|
|
100
101
|
end
|
|
101
102
|
|
|
102
103
|
def upsert(kind, item)
|
|
103
104
|
new_state = @core.upsert_internal(kind, item)
|
|
104
105
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
cache = @cache
|
|
107
|
+
unless cache.nil?
|
|
108
|
+
cache[item_cache_key(kind, item[:key])] = [new_state]
|
|
109
|
+
cache.delete(all_cache_key(kind))
|
|
108
110
|
end
|
|
109
111
|
end
|
|
110
112
|
|
|
@@ -115,13 +117,14 @@ module LaunchDarkly
|
|
|
115
117
|
def initialized?
|
|
116
118
|
return true if @inited.value
|
|
117
119
|
|
|
118
|
-
|
|
120
|
+
cache = @cache
|
|
121
|
+
if cache.nil?
|
|
119
122
|
result = @core.initialized_internal?
|
|
120
123
|
else
|
|
121
|
-
result =
|
|
124
|
+
result = cache[inited_cache_key]
|
|
122
125
|
if result.nil?
|
|
123
126
|
result = @core.initialized_internal?
|
|
124
|
-
|
|
127
|
+
cache[inited_cache_key] = result
|
|
125
128
|
end
|
|
126
129
|
end
|
|
127
130
|
|
|
@@ -129,6 +132,23 @@ module LaunchDarkly
|
|
|
129
132
|
result
|
|
130
133
|
end
|
|
131
134
|
|
|
135
|
+
#
|
|
136
|
+
# Disable the in-memory cache. Releases the cache reference so subsequent operations
|
|
137
|
+
# bypass it and go directly to the underlying core. Safe to call multiple times.
|
|
138
|
+
#
|
|
139
|
+
# Called by the FDv2 store coordinator once the in-memory store has become the
|
|
140
|
+
# source of truth and the persistent-store cache is no longer useful. Internal --
|
|
141
|
+
# not part of the public API.
|
|
142
|
+
#
|
|
143
|
+
# @return [void]
|
|
144
|
+
#
|
|
145
|
+
def disable_cache
|
|
146
|
+
cache = @cache
|
|
147
|
+
return if cache.nil?
|
|
148
|
+
@cache = nil
|
|
149
|
+
cache.clear
|
|
150
|
+
end
|
|
151
|
+
|
|
132
152
|
def stop
|
|
133
153
|
@core.stop
|
|
134
154
|
end
|
|
@@ -6,9 +6,6 @@ module LaunchDarkly
|
|
|
6
6
|
#
|
|
7
7
|
# EventName represents the name of an event that can be sent by the server for FDv2.
|
|
8
8
|
#
|
|
9
|
-
# This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
10
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
11
|
-
#
|
|
12
9
|
module EventName
|
|
13
10
|
# Specifies that an object should be added to the data set with upsert semantics.
|
|
14
11
|
PUT_OBJECT = :"put-object"
|
|
@@ -35,9 +32,6 @@ module LaunchDarkly
|
|
|
35
32
|
#
|
|
36
33
|
# ObjectKind represents the kind of object.
|
|
37
34
|
#
|
|
38
|
-
# This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
39
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
40
|
-
#
|
|
41
35
|
module ObjectKind
|
|
42
36
|
# Represents a feature flag.
|
|
43
37
|
FLAG = "flag"
|
|
@@ -49,9 +43,6 @@ module LaunchDarkly
|
|
|
49
43
|
#
|
|
50
44
|
# ChangeType specifies if an object is being upserted or deleted.
|
|
51
45
|
#
|
|
52
|
-
# This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
53
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
54
|
-
#
|
|
55
46
|
module ChangeType
|
|
56
47
|
# Represents an object being upserted.
|
|
57
48
|
PUT = "put"
|
|
@@ -63,9 +54,6 @@ module LaunchDarkly
|
|
|
63
54
|
#
|
|
64
55
|
# IntentCode represents the various intents that can be sent by the server.
|
|
65
56
|
#
|
|
66
|
-
# This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
67
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
68
|
-
#
|
|
69
57
|
module IntentCode
|
|
70
58
|
# The server intends to send a full data set.
|
|
71
59
|
TRANSFER_FULL = "xfer-full"
|
|
@@ -80,9 +68,6 @@ module LaunchDarkly
|
|
|
80
68
|
#
|
|
81
69
|
# DataStoreMode represents the mode of operation of a Data Store in FDV2 mode.
|
|
82
70
|
#
|
|
83
|
-
# This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
84
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
85
|
-
#
|
|
86
71
|
module DataStoreMode
|
|
87
72
|
# Indicates that the data store is read-only. Data will never be written back to the store by the SDK.
|
|
88
73
|
READ_ONLY = :read_only
|
|
@@ -95,9 +80,6 @@ module LaunchDarkly
|
|
|
95
80
|
#
|
|
96
81
|
# Selector represents a particular snapshot of data.
|
|
97
82
|
#
|
|
98
|
-
# This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
99
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
100
|
-
#
|
|
101
83
|
class Selector
|
|
102
84
|
# @return [String] The state
|
|
103
85
|
attr_reader :state
|
|
@@ -196,9 +178,6 @@ module LaunchDarkly
|
|
|
196
178
|
#
|
|
197
179
|
# Change represents a change to a piece of data, such as an update or deletion.
|
|
198
180
|
#
|
|
199
|
-
# This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
200
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
201
|
-
#
|
|
202
181
|
class Change
|
|
203
182
|
# @return [String] The action ({ChangeType})
|
|
204
183
|
attr_reader :action
|
|
@@ -234,9 +213,6 @@ module LaunchDarkly
|
|
|
234
213
|
#
|
|
235
214
|
# ChangeSet represents a list of changes to be applied.
|
|
236
215
|
#
|
|
237
|
-
# This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
238
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
239
|
-
#
|
|
240
216
|
class ChangeSet
|
|
241
217
|
# @return [String] The intent code ({IntentCode})
|
|
242
218
|
attr_reader :intent_code
|
|
@@ -262,9 +238,6 @@ module LaunchDarkly
|
|
|
262
238
|
#
|
|
263
239
|
# Basis represents the initial payload of data that a data source can provide.
|
|
264
240
|
#
|
|
265
|
-
# This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
266
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
267
|
-
#
|
|
268
241
|
class Basis
|
|
269
242
|
# @return [ChangeSet] The change set
|
|
270
243
|
attr_reader :change_set
|
|
@@ -290,9 +263,6 @@ module LaunchDarkly
|
|
|
290
263
|
#
|
|
291
264
|
# Payload represents a payload delivered in a streaming response.
|
|
292
265
|
#
|
|
293
|
-
# This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
294
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
295
|
-
#
|
|
296
266
|
class Payload
|
|
297
267
|
# @return [String] The payload ID
|
|
298
268
|
attr_reader :id
|
|
@@ -357,9 +327,6 @@ module LaunchDarkly
|
|
|
357
327
|
#
|
|
358
328
|
# ServerIntent represents the type of change associated with the payload.
|
|
359
329
|
#
|
|
360
|
-
# This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
361
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
362
|
-
#
|
|
363
330
|
class ServerIntent
|
|
364
331
|
# @return [Payload] The payload
|
|
365
332
|
attr_reader :payload
|
|
@@ -405,9 +372,6 @@ module LaunchDarkly
|
|
|
405
372
|
#
|
|
406
373
|
# ChangeSetBuilder is a helper for constructing a ChangeSet.
|
|
407
374
|
#
|
|
408
|
-
# This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
409
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
410
|
-
#
|
|
411
375
|
class ChangeSetBuilder
|
|
412
376
|
# @return [String, nil] The current intent ({IntentCode})
|
|
413
377
|
attr_accessor :intent
|
|
@@ -546,9 +510,6 @@ module LaunchDarkly
|
|
|
546
510
|
#
|
|
547
511
|
# Update represents the results of a synchronizer's ongoing sync method.
|
|
548
512
|
#
|
|
549
|
-
# This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
550
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
551
|
-
#
|
|
552
513
|
class Update
|
|
553
514
|
# @return [Symbol] The data source state ({LaunchDarkly::Interfaces::DataSource::Status})
|
|
554
515
|
attr_reader :state
|
|
@@ -559,8 +520,9 @@ module LaunchDarkly
|
|
|
559
520
|
# @return [LaunchDarkly::Interfaces::DataSource::ErrorInfo, nil] Error information
|
|
560
521
|
attr_reader :error
|
|
561
522
|
|
|
562
|
-
# @return [Boolean] Whether
|
|
563
|
-
|
|
523
|
+
# @return [Boolean] Whether the LaunchDarkly server has instructed the SDK to fall
|
|
524
|
+
# back to the FDv1 protocol (signalled via the `X-LD-FD-Fallback` response header).
|
|
525
|
+
attr_reader :fallback_to_fdv1
|
|
564
526
|
|
|
565
527
|
# @return [String, nil] The environment ID
|
|
566
528
|
attr_reader :environment_id
|
|
@@ -569,23 +531,67 @@ module LaunchDarkly
|
|
|
569
531
|
# @param state [Symbol] The data source state ({LaunchDarkly::Interfaces::DataSource::Status})
|
|
570
532
|
# @param change_set [ChangeSet, nil] The change set
|
|
571
533
|
# @param error [LaunchDarkly::Interfaces::DataSource::ErrorInfo, nil] Error information
|
|
572
|
-
# @param
|
|
534
|
+
# @param fallback_to_fdv1 [Boolean] Whether to fall back to FDv1
|
|
573
535
|
# @param environment_id [String, nil] The environment ID
|
|
574
536
|
#
|
|
575
|
-
def initialize(state:, change_set: nil, error: nil,
|
|
537
|
+
def initialize(state:, change_set: nil, error: nil, fallback_to_fdv1: false, environment_id: nil)
|
|
576
538
|
@state = state
|
|
577
539
|
@change_set = change_set
|
|
578
540
|
@error = error
|
|
579
|
-
@
|
|
541
|
+
@fallback_to_fdv1 = fallback_to_fdv1
|
|
580
542
|
@environment_id = environment_id
|
|
581
543
|
end
|
|
582
544
|
end
|
|
583
545
|
|
|
584
546
|
#
|
|
585
|
-
#
|
|
547
|
+
# FetchResult pairs the result of an {Initializer#fetch} call with the
|
|
548
|
+
# server-directed FDv1 Fallback Directive signal.
|
|
549
|
+
#
|
|
550
|
+
# When the LaunchDarkly server returns the `X-LD-FD-Fallback: true`
|
|
551
|
+
# response header on an initializer response, the SDK must apply any
|
|
552
|
+
# accompanying payload and then switch to the FDv1 Fallback Synchronizer.
|
|
553
|
+
# Surfacing this signal alongside the {LaunchDarkly::Result} ensures
|
|
554
|
+
# callers cannot silently drop it.
|
|
555
|
+
#
|
|
556
|
+
class FetchResult
|
|
557
|
+
# @return [LaunchDarkly::Result] A Result containing either a {Basis} or an error.
|
|
558
|
+
attr_reader :result
|
|
559
|
+
|
|
560
|
+
# @return [Boolean] Whether the server has instructed the SDK to fall back to the FDv1 protocol.
|
|
561
|
+
attr_reader :fallback_to_fdv1
|
|
562
|
+
|
|
563
|
+
#
|
|
564
|
+
# @param result [LaunchDarkly::Result] A Result containing either a Basis or an error.
|
|
565
|
+
# @param fallback_to_fdv1 [Boolean] Whether to fall back to FDv1.
|
|
566
|
+
#
|
|
567
|
+
def initialize(result:, fallback_to_fdv1: false)
|
|
568
|
+
@result = result
|
|
569
|
+
@fallback_to_fdv1 = fallback_to_fdv1
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
# @return [Boolean] true when the underlying Result was successful.
|
|
573
|
+
def success?
|
|
574
|
+
@result.success?
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
# @return [Object, nil] The {Basis} returned from a successful fetch, or nil.
|
|
578
|
+
def value
|
|
579
|
+
@result.value
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
# @return [String, nil] An error description, or nil on success.
|
|
583
|
+
def error
|
|
584
|
+
@result.error
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
# @return [Exception, nil] An optional exception describing the failure.
|
|
588
|
+
def exception
|
|
589
|
+
@result.exception
|
|
590
|
+
end
|
|
591
|
+
end
|
|
592
|
+
|
|
586
593
|
#
|
|
587
|
-
#
|
|
588
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
594
|
+
# SelectorStore represents a component capable of providing Selectors for data retrieval.
|
|
589
595
|
#
|
|
590
596
|
module SelectorStore
|
|
591
597
|
#
|
|
@@ -601,9 +607,6 @@ module LaunchDarkly
|
|
|
601
607
|
#
|
|
602
608
|
# ReadOnlyStore represents a read-only store interface for retrieving data.
|
|
603
609
|
#
|
|
604
|
-
# This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
605
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
606
|
-
#
|
|
607
610
|
module ReadOnlyStore
|
|
608
611
|
#
|
|
609
612
|
# Retrieves an item by kind and key.
|
|
@@ -639,9 +642,6 @@ module LaunchDarkly
|
|
|
639
642
|
#
|
|
640
643
|
# Initializer represents a component capable of retrieving a single data result.
|
|
641
644
|
#
|
|
642
|
-
# This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
643
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
644
|
-
#
|
|
645
645
|
module Initializer
|
|
646
646
|
#
|
|
647
647
|
# Returns the name of the initializer.
|
|
@@ -655,8 +655,14 @@ module LaunchDarkly
|
|
|
655
655
|
#
|
|
656
656
|
# Retrieves the initial data set for the data source.
|
|
657
657
|
#
|
|
658
|
+
# If the LaunchDarkly server has instructed the SDK to fall back to
|
|
659
|
+
# the FDv1 protocol, the returned {FetchResult#fallback_to_fdv1} is
|
|
660
|
+
# true. The wrapped result may still carry a successful {Basis} when
|
|
661
|
+
# the directive accompanied a valid payload, in which case callers
|
|
662
|
+
# should apply the payload before switching protocols.
|
|
663
|
+
#
|
|
658
664
|
# @param selector_store [SelectorStore] Provides the Selector
|
|
659
|
-
# @return [
|
|
665
|
+
# @return [FetchResult]
|
|
660
666
|
#
|
|
661
667
|
def fetch(selector_store)
|
|
662
668
|
raise NotImplementedError, "#{self.class} must implement #fetch"
|
|
@@ -666,9 +672,6 @@ module LaunchDarkly
|
|
|
666
672
|
#
|
|
667
673
|
# Synchronizer represents a component capable of synchronizing data from an external source.
|
|
668
674
|
#
|
|
669
|
-
# This type is not stable, and not subject to any backwards compatibility guarantees or semantic versioning.
|
|
670
|
-
# It is in early access. If you want access to this feature please join the EAP. https://launchdarkly.com/docs/sdk/features/data-saving-mode
|
|
671
|
-
#
|
|
672
675
|
module Synchronizer
|
|
673
676
|
#
|
|
674
677
|
# Returns the name of the synchronizer.
|
|
@@ -70,17 +70,27 @@ module LaunchDarkly
|
|
|
70
70
|
attr_reader :default_value
|
|
71
71
|
attr_reader :method
|
|
72
72
|
|
|
73
|
+
#
|
|
74
|
+
# The ID of the LaunchDarkly environment the SDK is connected to, if known. This is only available once the
|
|
75
|
+
# SDK has received data from LaunchDarkly.
|
|
76
|
+
#
|
|
77
|
+
# @return [String, nil]
|
|
78
|
+
#
|
|
79
|
+
attr_reader :environment_id
|
|
80
|
+
|
|
73
81
|
#
|
|
74
82
|
# @param key [String]
|
|
75
83
|
# @param context [LaunchDarkly::LDContext]
|
|
76
84
|
# @param default_value [any]
|
|
77
85
|
# @param method [Symbol]
|
|
86
|
+
# @param environment_id [String, nil]
|
|
78
87
|
#
|
|
79
|
-
def initialize(key, context, default_value, method)
|
|
88
|
+
def initialize(key, context, default_value, method, environment_id = nil)
|
|
80
89
|
@key = key
|
|
81
90
|
@context = context
|
|
82
91
|
@default_value = default_value
|
|
83
92
|
@method = method
|
|
93
|
+
@environment_id = environment_id
|
|
84
94
|
end
|
|
85
95
|
end
|
|
86
96
|
end
|
data/lib/ldclient-rb/ldclient.rb
CHANGED
|
@@ -421,7 +421,7 @@ module LaunchDarkly
|
|
|
421
421
|
# Hooks can be added and we want to ensure all correct stages for a given hook execute. For example, we do not
|
|
422
422
|
# want to trigger the after_evaluation method without also triggering the before_evaluation method.
|
|
423
423
|
hooks = @hooks.dup
|
|
424
|
-
evaluation_series_context = Interfaces::Hooks::EvaluationSeriesContext.new(key, context, default, method)
|
|
424
|
+
evaluation_series_context = Interfaces::Hooks::EvaluationSeriesContext.new(key, context, default, method, @data_system.environment_id)
|
|
425
425
|
|
|
426
426
|
[hooks, evaluation_series_context]
|
|
427
427
|
end
|
data/lib/ldclient-rb/util.rb
CHANGED
|
@@ -16,10 +16,11 @@ module LaunchDarkly
|
|
|
16
16
|
# Create a successful result with the provided value.
|
|
17
17
|
#
|
|
18
18
|
# @param value [Object, nil]
|
|
19
|
+
# @param headers [Hash, nil] Optional headers associated with the result
|
|
19
20
|
# @return [Result]
|
|
20
21
|
#
|
|
21
|
-
def self.success(value)
|
|
22
|
-
Result.new(value)
|
|
22
|
+
def self.success(value, headers = nil)
|
|
23
|
+
Result.new(value, nil, nil, headers)
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
#
|
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.15.0
|
|
5
5
|
platform: java
|
|
6
6
|
authors:
|
|
7
7
|
- LaunchDarkly
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-08-20 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: aws-sdk-dynamodb
|