launchdarkly-server-sdk 6.3.4 → 7.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ldclient-rb/config.rb +121 -55
- data/lib/ldclient-rb/context.rb +487 -0
- data/lib/ldclient-rb/evaluation_detail.rb +20 -20
- data/lib/ldclient-rb/events.rb +77 -132
- data/lib/ldclient-rb/flags_state.rb +4 -4
- data/lib/ldclient-rb/impl/big_segments.rb +17 -17
- data/lib/ldclient-rb/impl/context.rb +96 -0
- data/lib/ldclient-rb/impl/context_filter.rb +145 -0
- data/lib/ldclient-rb/impl/diagnostic_events.rb +9 -10
- data/lib/ldclient-rb/impl/evaluator.rb +378 -139
- data/lib/ldclient-rb/impl/evaluator_bucketing.rb +40 -41
- data/lib/ldclient-rb/impl/evaluator_helpers.rb +50 -0
- data/lib/ldclient-rb/impl/evaluator_operators.rb +26 -55
- data/lib/ldclient-rb/impl/event_sender.rb +6 -6
- data/lib/ldclient-rb/impl/event_summarizer.rb +12 -7
- data/lib/ldclient-rb/impl/event_types.rb +18 -30
- data/lib/ldclient-rb/impl/integrations/consul_impl.rb +7 -7
- data/lib/ldclient-rb/impl/integrations/dynamodb_impl.rb +29 -29
- data/lib/ldclient-rb/impl/integrations/file_data_source.rb +8 -8
- data/lib/ldclient-rb/impl/integrations/redis_impl.rb +92 -12
- data/lib/ldclient-rb/impl/model/clause.rb +39 -0
- data/lib/ldclient-rb/impl/model/feature_flag.rb +213 -0
- data/lib/ldclient-rb/impl/model/preprocessed_data.rb +64 -0
- data/lib/ldclient-rb/impl/model/segment.rb +126 -0
- data/lib/ldclient-rb/impl/model/serialization.rb +54 -44
- data/lib/ldclient-rb/impl/repeating_task.rb +1 -1
- data/lib/ldclient-rb/impl/store_data_set_sorter.rb +2 -2
- data/lib/ldclient-rb/impl/unbounded_pool.rb +1 -1
- data/lib/ldclient-rb/impl/util.rb +59 -1
- data/lib/ldclient-rb/in_memory_store.rb +2 -2
- data/lib/ldclient-rb/integrations/consul.rb +1 -1
- data/lib/ldclient-rb/integrations/dynamodb.rb +1 -1
- data/lib/ldclient-rb/integrations/file_data.rb +3 -3
- data/lib/ldclient-rb/integrations/redis.rb +4 -4
- data/lib/ldclient-rb/integrations/test_data/flag_builder.rb +218 -62
- data/lib/ldclient-rb/integrations/test_data.rb +16 -12
- data/lib/ldclient-rb/integrations/util/store_wrapper.rb +9 -9
- data/lib/ldclient-rb/interfaces.rb +14 -14
- data/lib/ldclient-rb/ldclient.rb +94 -144
- data/lib/ldclient-rb/memoized_value.rb +1 -1
- data/lib/ldclient-rb/non_blocking_thread_pool.rb +1 -1
- data/lib/ldclient-rb/polling.rb +2 -2
- data/lib/ldclient-rb/reference.rb +274 -0
- data/lib/ldclient-rb/requestor.rb +7 -7
- data/lib/ldclient-rb/stream.rb +8 -9
- data/lib/ldclient-rb/util.rb +4 -19
- data/lib/ldclient-rb/version.rb +1 -1
- data/lib/ldclient-rb.rb +2 -3
- metadata +36 -17
- data/lib/ldclient-rb/file_data_source.rb +0 -23
- data/lib/ldclient-rb/newrelic.rb +0 -17
- data/lib/ldclient-rb/redis_store.rb +0 -88
- data/lib/ldclient-rb/user_filter.rb +0 -52
@@ -0,0 +1,274 @@
|
|
1
|
+
module LaunchDarkly
|
2
|
+
#
|
3
|
+
# Reference is an attribute name or path expression identifying a value
|
4
|
+
# within a Context.
|
5
|
+
#
|
6
|
+
# This type is mainly intended to be used internally by LaunchDarkly SDK and
|
7
|
+
# service code, where efficiency is a major concern so it's desirable to do
|
8
|
+
# any parsing or preprocessing just once. Applications are unlikely to need
|
9
|
+
# to use the Reference type directly.
|
10
|
+
#
|
11
|
+
# It can be used to retrieve a value with LDContext.get_value_for_reference()
|
12
|
+
# or to identify an attribute or nested value that should be considered
|
13
|
+
# private.
|
14
|
+
#
|
15
|
+
# Parsing and validation are done at the time that the Reference is
|
16
|
+
# constructed. If a Reference instance was created from an invalid string, it
|
17
|
+
# is considered invalid and its {Reference#error} attribute will return a
|
18
|
+
# non-nil error.
|
19
|
+
#
|
20
|
+
# ## Syntax
|
21
|
+
#
|
22
|
+
# The string representation of an attribute reference in LaunchDarkly JSON
|
23
|
+
# data uses the following syntax:
|
24
|
+
#
|
25
|
+
# If the first character is not a slash, the string is interpreted literally
|
26
|
+
# as an attribute name. An attribute name can contain any characters, but
|
27
|
+
# must not be empty.
|
28
|
+
#
|
29
|
+
# If the first character is a slash, the string is interpreted as a
|
30
|
+
# slash-delimited path where the first path component is an attribute name,
|
31
|
+
# and each subsequent path component is the name of a property in a JSON
|
32
|
+
# object. Any instances of the characters "/" or "~" in a path component are
|
33
|
+
# escaped as "~1" or "~0" respectively. This syntax deliberately resembles
|
34
|
+
# JSON Pointer, but no JSON Pointer behaviors other than those mentioned here
|
35
|
+
# are supported.
|
36
|
+
#
|
37
|
+
# ## Examples
|
38
|
+
#
|
39
|
+
# Suppose there is a context whose JSON implementation looks like this:
|
40
|
+
#
|
41
|
+
# {
|
42
|
+
# "kind": "user",
|
43
|
+
# "key": "value1",
|
44
|
+
# "address": {
|
45
|
+
# "street": {
|
46
|
+
# "line1": "value2",
|
47
|
+
# "line2": "value3"
|
48
|
+
# },
|
49
|
+
# "city": "value4"
|
50
|
+
# },
|
51
|
+
# "good/bad": "value5"
|
52
|
+
# }
|
53
|
+
#
|
54
|
+
# The attribute references "key" and "/key" would both point to "value1".
|
55
|
+
#
|
56
|
+
# The attribute reference "/address/street/line1" would point to "value2".
|
57
|
+
#
|
58
|
+
# The attribute references "good/bad" and "/good~1bad" would both point to
|
59
|
+
# "value5".
|
60
|
+
#
|
61
|
+
class Reference
|
62
|
+
ERR_EMPTY = 'empty reference'
|
63
|
+
private_constant :ERR_EMPTY
|
64
|
+
|
65
|
+
ERR_INVALID_ESCAPE_SEQUENCE = 'invalid escape sequence'
|
66
|
+
private_constant :ERR_INVALID_ESCAPE_SEQUENCE
|
67
|
+
|
68
|
+
ERR_DOUBLE_TRAILING_SLASH = 'double or trailing slash'
|
69
|
+
private_constant :ERR_DOUBLE_TRAILING_SLASH
|
70
|
+
|
71
|
+
#
|
72
|
+
# Returns nil for a valid Reference, or a non-nil error value for an
|
73
|
+
# invalid Reference.
|
74
|
+
#
|
75
|
+
# A Reference is invalid if the input string is empty, or starts with a
|
76
|
+
# slash but is not a valid slash-delimited path, or starts with a slash and
|
77
|
+
# contains an invalid escape sequence.
|
78
|
+
#
|
79
|
+
# Otherwise, the Reference is valid, but that does not guarantee that such
|
80
|
+
# an attribute exists in any given Context. For instance,
|
81
|
+
# Reference.create("name") is a valid Reference, but a specific Context
|
82
|
+
# might or might not have a name.
|
83
|
+
#
|
84
|
+
# See comments on the Reference type for more details of the attribute
|
85
|
+
# reference syntax.
|
86
|
+
#
|
87
|
+
# @return [String, nil]
|
88
|
+
#
|
89
|
+
attr_reader :error
|
90
|
+
|
91
|
+
#
|
92
|
+
# Returns the attribute reference as a string, in the same format provided
|
93
|
+
# to {#create}.
|
94
|
+
#
|
95
|
+
# If the Reference was created with {#create}, this value is identical to
|
96
|
+
# the original string. If it was created with {#create_literal}, the value
|
97
|
+
# may be different due to unescaping (for instance, an attribute whose name
|
98
|
+
# is "/a" would be represented as "~1a").
|
99
|
+
#
|
100
|
+
# @return [String, nil]
|
101
|
+
#
|
102
|
+
attr_reader :raw_path
|
103
|
+
|
104
|
+
def initialize(raw_path, components = [], error = nil)
|
105
|
+
@raw_path = raw_path
|
106
|
+
# @type [Array<Symbol>]
|
107
|
+
@components = components
|
108
|
+
@error = error
|
109
|
+
end
|
110
|
+
private_class_method :new
|
111
|
+
|
112
|
+
#
|
113
|
+
# Creates a Reference from a string. For the supported syntax and examples,
|
114
|
+
# see comments on the Reference type.
|
115
|
+
#
|
116
|
+
# This constructor always returns a Reference that preserves the original
|
117
|
+
# string, even if validation fails, so that accessing {#raw_path} (or
|
118
|
+
# serializing the Reference to JSON) will produce the original string. If
|
119
|
+
# validation fails, {#error} will return a non-nil error and any SDK method
|
120
|
+
# that takes this Reference as a parameter will consider it invalid.
|
121
|
+
#
|
122
|
+
# @param value [String, Symbol]
|
123
|
+
# @return [Reference]
|
124
|
+
#
|
125
|
+
def self.create(value)
|
126
|
+
unless value.is_a?(String) || value.is_a?(Symbol)
|
127
|
+
return new(value, [], ERR_EMPTY)
|
128
|
+
end
|
129
|
+
|
130
|
+
value = value.to_s if value.is_a?(Symbol)
|
131
|
+
|
132
|
+
return new(value, [], ERR_EMPTY) if value.empty? || value == "/"
|
133
|
+
|
134
|
+
unless value.start_with? "/"
|
135
|
+
return new(value, [value.to_sym])
|
136
|
+
end
|
137
|
+
|
138
|
+
if value.end_with? "/"
|
139
|
+
return new(value, [], ERR_DOUBLE_TRAILING_SLASH)
|
140
|
+
end
|
141
|
+
|
142
|
+
components = []
|
143
|
+
value[1..].split("/").each do |component|
|
144
|
+
if component.empty?
|
145
|
+
return new(value, [], ERR_DOUBLE_TRAILING_SLASH)
|
146
|
+
end
|
147
|
+
|
148
|
+
path, error = unescape_path(component)
|
149
|
+
|
150
|
+
if error
|
151
|
+
return new(value, [], error)
|
152
|
+
end
|
153
|
+
|
154
|
+
components << path.to_sym
|
155
|
+
end
|
156
|
+
|
157
|
+
new(value, components)
|
158
|
+
end
|
159
|
+
|
160
|
+
#
|
161
|
+
# create_literal is similar to {#create} except that it always
|
162
|
+
# interprets the string as a literal attribute name, never as a
|
163
|
+
# slash-delimited path expression. There is no escaping or unescaping, even
|
164
|
+
# if the name contains literal '/' or '~' characters. Since an attribute
|
165
|
+
# name can contain any characters, this method always returns a valid
|
166
|
+
# Reference unless the name is empty.
|
167
|
+
#
|
168
|
+
# For example: Reference.create_literal("name") is exactly equivalent to
|
169
|
+
# Reference.create("name"). Reference.create_literal("a/b") is exactly
|
170
|
+
# equivalent to Reference.create("a/b") (since the syntax used by {#create}
|
171
|
+
# treats the whole string as a literal as long as it does not start with a
|
172
|
+
# slash), or to Reference.create("/a~1b").
|
173
|
+
#
|
174
|
+
# @param value [String, Symbol]
|
175
|
+
# @return [Reference]
|
176
|
+
#
|
177
|
+
def self.create_literal(value)
|
178
|
+
unless value.is_a?(String) || value.is_a?(Symbol)
|
179
|
+
return new(value, [], ERR_EMPTY)
|
180
|
+
end
|
181
|
+
|
182
|
+
value = value.to_s if value.is_a?(Symbol)
|
183
|
+
|
184
|
+
return new(value, [], ERR_EMPTY) if value.empty?
|
185
|
+
return new(value, [value.to_sym]) if value[0] != '/'
|
186
|
+
|
187
|
+
escaped = "/" + value.gsub('~', '~0').gsub('/', '~1')
|
188
|
+
new(escaped, [value.to_sym])
|
189
|
+
end
|
190
|
+
|
191
|
+
#
|
192
|
+
# Returns the number of path components in the Reference.
|
193
|
+
#
|
194
|
+
# For a simple attribute reference such as "name" with no leading slash,
|
195
|
+
# this returns 1.
|
196
|
+
#
|
197
|
+
# For an attribute reference with a leading slash, it is the number of
|
198
|
+
# slash-delimited path components after the initial slash. For instance,
|
199
|
+
# NewRef("/a/b").Depth() returns 2.
|
200
|
+
#
|
201
|
+
# @return [Integer]
|
202
|
+
#
|
203
|
+
def depth
|
204
|
+
@components.size
|
205
|
+
end
|
206
|
+
|
207
|
+
#
|
208
|
+
# Retrieves a single path component from the attribute reference.
|
209
|
+
#
|
210
|
+
# For a simple attribute reference such as "name" with no leading slash, if
|
211
|
+
# index is zero, {#component} returns the attribute name as a symbol.
|
212
|
+
#
|
213
|
+
# For an attribute reference with a leading slash, if index is non-negative
|
214
|
+
# and less than {#depth}, Component returns the path component as a symbol.
|
215
|
+
#
|
216
|
+
# If index is out of range, it returns nil.
|
217
|
+
#
|
218
|
+
# Reference.create("a").component(0) # returns "a"
|
219
|
+
# Reference.create("/a/b").component(1) # returns "b"
|
220
|
+
#
|
221
|
+
# @param index [Integer]
|
222
|
+
# @return [Symbol, nil]
|
223
|
+
#
|
224
|
+
def component(index)
|
225
|
+
return nil if index < 0 || index >= depth
|
226
|
+
|
227
|
+
@components[index]
|
228
|
+
end
|
229
|
+
|
230
|
+
#
|
231
|
+
# Performs unescaping of attribute reference path components:
|
232
|
+
#
|
233
|
+
# "~1" becomes "/"
|
234
|
+
# "~0" becomes "~"
|
235
|
+
# "~" followed by any character other than "0" or "1" is invalid
|
236
|
+
#
|
237
|
+
# This method returns an array of two values. The first element of the
|
238
|
+
# array is the path if unescaping was valid; otherwise, it will be nil. The
|
239
|
+
# second value is an error string, or nil if the unescaping was successful.
|
240
|
+
#
|
241
|
+
# @param path [String]
|
242
|
+
# @return [Array([String, nil], [String, nil])] Returns a fixed size array.
|
243
|
+
#
|
244
|
+
private_class_method def self.unescape_path(path)
|
245
|
+
# If there are no tildes then there's definitely nothing to do
|
246
|
+
return path, nil unless path.include? '~'
|
247
|
+
|
248
|
+
out = ""
|
249
|
+
i = 0
|
250
|
+
while i < path.size
|
251
|
+
if path[i] != "~"
|
252
|
+
out << path[i]
|
253
|
+
i += 1
|
254
|
+
next
|
255
|
+
end
|
256
|
+
|
257
|
+
return nil, ERR_INVALID_ESCAPE_SEQUENCE if i + 1 == path.size
|
258
|
+
|
259
|
+
case path[i + 1]
|
260
|
+
when '0'
|
261
|
+
out << "~"
|
262
|
+
when '1'
|
263
|
+
out << '/'
|
264
|
+
else
|
265
|
+
return nil, ERR_INVALID_ESCAPE_SEQUENCE
|
266
|
+
end
|
267
|
+
|
268
|
+
i += 2
|
269
|
+
end
|
270
|
+
|
271
|
+
[out, nil]
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
@@ -31,9 +31,9 @@ module LaunchDarkly
|
|
31
31
|
|
32
32
|
def request_all_data()
|
33
33
|
all_data = JSON.parse(make_request("/sdk/latest-all"), symbolize_names: true)
|
34
|
-
Impl::Model.make_all_store_data(all_data)
|
34
|
+
Impl::Model.make_all_store_data(all_data, @config.logger)
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def stop
|
38
38
|
begin
|
39
39
|
@http_client.close
|
@@ -44,7 +44,7 @@ module LaunchDarkly
|
|
44
44
|
private
|
45
45
|
|
46
46
|
def request_single_item(kind, path)
|
47
|
-
Impl::Model.deserialize(kind, make_request(path))
|
47
|
+
Impl::Model.deserialize(kind, make_request(path), @config.logger)
|
48
48
|
end
|
49
49
|
|
50
50
|
def make_request(path)
|
@@ -53,11 +53,11 @@ module LaunchDarkly
|
|
53
53
|
Impl::Util.default_http_headers(@sdk_key, @config).each { |k, v| headers[k] = v }
|
54
54
|
headers["Connection"] = "keep-alive"
|
55
55
|
cached = @cache.read(uri)
|
56
|
-
|
56
|
+
unless cached.nil?
|
57
57
|
headers["If-None-Match"] = cached.etag
|
58
58
|
end
|
59
59
|
response = @http_client.request("GET", uri, {
|
60
|
-
headers: headers
|
60
|
+
headers: headers,
|
61
61
|
})
|
62
62
|
status = response.status.code
|
63
63
|
# must fully read body for persistent connections
|
@@ -72,7 +72,7 @@ module LaunchDarkly
|
|
72
72
|
end
|
73
73
|
body = fix_encoding(body, response.headers["content-type"])
|
74
74
|
etag = response.headers["etag"]
|
75
|
-
@cache.write(uri, CacheEntry.new(etag, body))
|
75
|
+
@cache.write(uri, CacheEntry.new(etag, body)) unless etag.nil?
|
76
76
|
end
|
77
77
|
body
|
78
78
|
end
|
@@ -96,7 +96,7 @@ module LaunchDarkly
|
|
96
96
|
break
|
97
97
|
end
|
98
98
|
end
|
99
|
-
|
99
|
+
[parts[0], charset]
|
100
100
|
end
|
101
101
|
end
|
102
102
|
end
|
data/lib/ldclient-rb/stream.rb
CHANGED
@@ -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
|
@@ -41,14 +41,14 @@ module LaunchDarkly
|
|
41
41
|
return @ready unless @started.make_true
|
42
42
|
|
43
43
|
@config.logger.info { "[LDClient] Initializing stream connection" }
|
44
|
-
|
44
|
+
|
45
45
|
headers = Impl::Util.default_http_headers(@sdk_key, @config)
|
46
46
|
opts = {
|
47
47
|
headers: headers,
|
48
48
|
read_timeout: READ_TIMEOUT_SECONDS,
|
49
49
|
logger: @config.logger,
|
50
50
|
socket_factory: @config.socket_factory,
|
51
|
-
reconnect_time: @config.initial_reconnect_delay
|
51
|
+
reconnect_time: @config.initial_reconnect_delay,
|
52
52
|
}
|
53
53
|
log_connection_started
|
54
54
|
@es = SSE::Client.new(@config.stream_uri + "/all", **opts) do |conn|
|
@@ -60,14 +60,14 @@ module LaunchDarkly
|
|
60
60
|
status = err.status
|
61
61
|
message = Util.http_error_message(status, "streaming connection", "will retry")
|
62
62
|
@config.logger.error { "[LDClient] #{message}" }
|
63
|
-
|
63
|
+
unless Util.http_error_recoverable?(status)
|
64
64
|
@ready.set # if client was waiting on us, make it stop waiting - has no effect if already set
|
65
65
|
stop
|
66
66
|
end
|
67
67
|
end
|
68
68
|
}
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
@ready
|
72
72
|
end
|
73
73
|
|
@@ -86,7 +86,7 @@ module LaunchDarkly
|
|
86
86
|
@config.logger.debug { "[LDClient] Stream received #{method} message: #{message.data}" }
|
87
87
|
if method == PUT
|
88
88
|
message = JSON.parse(message.data, symbolize_names: true)
|
89
|
-
all_data = Impl::Model.make_all_store_data(message[:data])
|
89
|
+
all_data = Impl::Model.make_all_store_data(message[:data], @config.logger)
|
90
90
|
@feature_store.init(all_data)
|
91
91
|
@initialized.make_true
|
92
92
|
@config.logger.info { "[LDClient] Stream initialized" }
|
@@ -96,9 +96,8 @@ module LaunchDarkly
|
|
96
96
|
for kind in [FEATURES, SEGMENTS]
|
97
97
|
key = key_for_path(kind, data[:path])
|
98
98
|
if key
|
99
|
-
|
100
|
-
|
101
|
-
@feature_store.upsert(kind, data)
|
99
|
+
item = Impl::Model.deserialize(kind, data[:data], @config.logger)
|
100
|
+
@feature_store.upsert(kind, item)
|
102
101
|
break
|
103
102
|
end
|
104
103
|
end
|
data/lib/ldclient-rb/util.rb
CHANGED
@@ -4,39 +4,24 @@ require "http"
|
|
4
4
|
module LaunchDarkly
|
5
5
|
# @private
|
6
6
|
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
|
18
|
-
end
|
19
|
-
ret
|
20
|
-
end
|
21
|
-
|
22
7
|
def self.new_http_client(uri_s, config)
|
23
8
|
http_client_options = {}
|
24
9
|
if config.socket_factory
|
25
10
|
http_client_options["socket_class"] = config.socket_factory
|
26
11
|
end
|
27
12
|
proxy = URI.parse(uri_s).find_proxy
|
28
|
-
|
13
|
+
unless proxy.nil?
|
29
14
|
http_client_options["proxy"] = {
|
30
15
|
proxy_address: proxy.host,
|
31
16
|
proxy_port: proxy.port,
|
32
17
|
proxy_username: proxy.user,
|
33
|
-
proxy_password: proxy.password
|
18
|
+
proxy_password: proxy.password,
|
34
19
|
}
|
35
20
|
end
|
36
|
-
|
21
|
+
HTTP::Client.new(http_client_options)
|
37
22
|
.timeout({
|
38
23
|
read: config.read_timeout,
|
39
|
-
connect: config.connect_timeout
|
24
|
+
connect: config.connect_timeout,
|
40
25
|
})
|
41
26
|
.persistent(uri_s)
|
42
27
|
end
|
data/lib/ldclient-rb/version.rb
CHANGED
data/lib/ldclient-rb.rb
CHANGED
@@ -15,13 +15,12 @@ require "ldclient-rb/expiring_cache"
|
|
15
15
|
require "ldclient-rb/memoized_value"
|
16
16
|
require "ldclient-rb/in_memory_store"
|
17
17
|
require "ldclient-rb/config"
|
18
|
-
require "ldclient-rb/
|
18
|
+
require "ldclient-rb/context"
|
19
|
+
require "ldclient-rb/reference"
|
19
20
|
require "ldclient-rb/stream"
|
20
21
|
require "ldclient-rb/polling"
|
21
|
-
require "ldclient-rb/user_filter"
|
22
22
|
require "ldclient-rb/simple_lru_cache"
|
23
23
|
require "ldclient-rb/non_blocking_thread_pool"
|
24
24
|
require "ldclient-rb/events"
|
25
25
|
require "ldclient-rb/requestor"
|
26
|
-
require "ldclient-rb/file_data_source"
|
27
26
|
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:
|
4
|
+
version: 7.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: 2022-
|
11
|
+
date: 2022-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-dynamodb
|
@@ -58,42 +58,42 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 2.
|
61
|
+
version: '2.6'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 2.
|
68
|
+
version: '2.6'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: redis
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '5.0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '5.0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: connection_pool
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 2.
|
89
|
+
version: '2.3'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 2.
|
96
|
+
version: '2.3'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rspec_junit_formatter
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -151,19 +151,33 @@ dependencies:
|
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '1.7'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
154
|
+
name: rubocop
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '1.37'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '1.37'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: rubocop-performance
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|
156
170
|
requirements:
|
157
171
|
- - "~>"
|
158
172
|
- !ruby/object:Gem::Version
|
159
|
-
version: '
|
173
|
+
version: '1.15'
|
160
174
|
type: :development
|
161
175
|
prerelease: false
|
162
176
|
version_requirements: !ruby/object:Gem::Requirement
|
163
177
|
requirements:
|
164
178
|
- - "~>"
|
165
179
|
- !ruby/object:Gem::Version
|
166
|
-
version: '
|
180
|
+
version: '1.15'
|
167
181
|
- !ruby/object:Gem::Dependency
|
168
182
|
name: semantic
|
169
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -253,16 +267,19 @@ files:
|
|
253
267
|
- lib/ldclient-rb.rb
|
254
268
|
- lib/ldclient-rb/cache_store.rb
|
255
269
|
- lib/ldclient-rb/config.rb
|
270
|
+
- lib/ldclient-rb/context.rb
|
256
271
|
- lib/ldclient-rb/evaluation_detail.rb
|
257
272
|
- lib/ldclient-rb/events.rb
|
258
273
|
- lib/ldclient-rb/expiring_cache.rb
|
259
|
-
- lib/ldclient-rb/file_data_source.rb
|
260
274
|
- lib/ldclient-rb/flags_state.rb
|
261
275
|
- lib/ldclient-rb/impl.rb
|
262
276
|
- lib/ldclient-rb/impl/big_segments.rb
|
277
|
+
- lib/ldclient-rb/impl/context.rb
|
278
|
+
- lib/ldclient-rb/impl/context_filter.rb
|
263
279
|
- lib/ldclient-rb/impl/diagnostic_events.rb
|
264
280
|
- lib/ldclient-rb/impl/evaluator.rb
|
265
281
|
- lib/ldclient-rb/impl/evaluator_bucketing.rb
|
282
|
+
- lib/ldclient-rb/impl/evaluator_helpers.rb
|
266
283
|
- lib/ldclient-rb/impl/evaluator_operators.rb
|
267
284
|
- lib/ldclient-rb/impl/event_sender.rb
|
268
285
|
- lib/ldclient-rb/impl/event_summarizer.rb
|
@@ -272,6 +289,10 @@ files:
|
|
272
289
|
- lib/ldclient-rb/impl/integrations/file_data_source.rb
|
273
290
|
- lib/ldclient-rb/impl/integrations/redis_impl.rb
|
274
291
|
- lib/ldclient-rb/impl/integrations/test_data/test_data_source.rb
|
292
|
+
- lib/ldclient-rb/impl/model/clause.rb
|
293
|
+
- lib/ldclient-rb/impl/model/feature_flag.rb
|
294
|
+
- lib/ldclient-rb/impl/model/preprocessed_data.rb
|
295
|
+
- lib/ldclient-rb/impl/model/segment.rb
|
275
296
|
- lib/ldclient-rb/impl/model/serialization.rb
|
276
297
|
- lib/ldclient-rb/impl/repeating_task.rb
|
277
298
|
- lib/ldclient-rb/impl/store_client_wrapper.rb
|
@@ -290,14 +311,12 @@ files:
|
|
290
311
|
- lib/ldclient-rb/interfaces.rb
|
291
312
|
- lib/ldclient-rb/ldclient.rb
|
292
313
|
- lib/ldclient-rb/memoized_value.rb
|
293
|
-
- lib/ldclient-rb/newrelic.rb
|
294
314
|
- lib/ldclient-rb/non_blocking_thread_pool.rb
|
295
315
|
- lib/ldclient-rb/polling.rb
|
296
|
-
- lib/ldclient-rb/
|
316
|
+
- lib/ldclient-rb/reference.rb
|
297
317
|
- lib/ldclient-rb/requestor.rb
|
298
318
|
- lib/ldclient-rb/simple_lru_cache.rb
|
299
319
|
- lib/ldclient-rb/stream.rb
|
300
|
-
- lib/ldclient-rb/user_filter.rb
|
301
320
|
- lib/ldclient-rb/util.rb
|
302
321
|
- lib/ldclient-rb/version.rb
|
303
322
|
homepage: https://github.com/launchdarkly/ruby-server-sdk
|
@@ -312,14 +331,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
312
331
|
requirements:
|
313
332
|
- - ">="
|
314
333
|
- !ruby/object:Gem::Version
|
315
|
-
version: 2.
|
334
|
+
version: 2.7.0
|
316
335
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
317
336
|
requirements:
|
318
337
|
- - ">="
|
319
338
|
- !ruby/object:Gem::Version
|
320
339
|
version: '0'
|
321
340
|
requirements: []
|
322
|
-
rubygems_version: 3.
|
341
|
+
rubygems_version: 3.4.1
|
323
342
|
signing_key:
|
324
343
|
specification_version: 4
|
325
344
|
summary: LaunchDarkly SDK for Ruby
|
@@ -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
|
data/lib/ldclient-rb/newrelic.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
module LaunchDarkly
|
2
|
-
# @private
|
3
|
-
class LDNewRelic
|
4
|
-
begin
|
5
|
-
require "newrelic_rpm"
|
6
|
-
NR_ENABLED = defined?(::NewRelic::Agent.add_custom_parameters)
|
7
|
-
rescue ScriptError, StandardError
|
8
|
-
NR_ENABLED = false
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.annotate_transaction(key, value)
|
12
|
-
if NR_ENABLED
|
13
|
-
::NewRelic::Agent.add_custom_parameters(key.to_s => value.to_s)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|