launchdarkly-server-sdk 6.2.5 → 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/README.md +1 -2
- data/lib/ldclient-rb/config.rb +203 -43
- data/lib/ldclient-rb/context.rb +487 -0
- data/lib/ldclient-rb/evaluation_detail.rb +85 -26
- data/lib/ldclient-rb/events.rb +185 -146
- data/lib/ldclient-rb/flags_state.rb +25 -14
- data/lib/ldclient-rb/impl/big_segments.rb +117 -0
- 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 +428 -132
- 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 +68 -0
- data/lib/ldclient-rb/impl/event_types.rb +78 -0
- data/lib/ldclient-rb/impl/integrations/consul_impl.rb +7 -7
- data/lib/ldclient-rb/impl/integrations/dynamodb_impl.rb +92 -28
- data/lib/ldclient-rb/impl/integrations/file_data_source.rb +212 -0
- data/lib/ldclient-rb/impl/integrations/redis_impl.rb +165 -32
- data/lib/ldclient-rb/impl/integrations/test_data/test_data_source.rb +40 -0
- 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 +47 -0
- 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 +62 -1
- data/lib/ldclient-rb/in_memory_store.rb +2 -2
- data/lib/ldclient-rb/integrations/consul.rb +9 -2
- 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 +43 -3
- data/lib/ldclient-rb/integrations/test_data/flag_builder.rb +594 -0
- data/lib/ldclient-rb/integrations/test_data.rb +213 -0
- data/lib/ldclient-rb/integrations/util/store_wrapper.rb +14 -9
- data/lib/ldclient-rb/integrations.rb +2 -51
- data/lib/ldclient-rb/interfaces.rb +151 -1
- data/lib/ldclient-rb/ldclient.rb +175 -133
- 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 +22 -41
- data/lib/ldclient-rb/reference.rb +274 -0
- data/lib/ldclient-rb/requestor.rb +7 -7
- data/lib/ldclient-rb/stream.rb +9 -9
- data/lib/ldclient-rb/util.rb +11 -17
- data/lib/ldclient-rb/version.rb +1 -1
- data/lib/ldclient-rb.rb +2 -4
- metadata +49 -23
- data/lib/ldclient-rb/event_summarizer.rb +0 -55
- data/lib/ldclient-rb/file_data_source.rb +0 -314
- data/lib/ldclient-rb/impl/event_factory.rb +0 -126
- 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,13 +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
|
-
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|
|
@@ -59,14 +60,14 @@ module LaunchDarkly
|
|
59
60
|
status = err.status
|
60
61
|
message = Util.http_error_message(status, "streaming connection", "will retry")
|
61
62
|
@config.logger.error { "[LDClient] #{message}" }
|
62
|
-
|
63
|
+
unless Util.http_error_recoverable?(status)
|
63
64
|
@ready.set # if client was waiting on us, make it stop waiting - has no effect if already set
|
64
65
|
stop
|
65
66
|
end
|
66
67
|
end
|
67
68
|
}
|
68
69
|
end
|
69
|
-
|
70
|
+
|
70
71
|
@ready
|
71
72
|
end
|
72
73
|
|
@@ -85,7 +86,7 @@ module LaunchDarkly
|
|
85
86
|
@config.logger.debug { "[LDClient] Stream received #{method} message: #{message.data}" }
|
86
87
|
if method == PUT
|
87
88
|
message = JSON.parse(message.data, symbolize_names: true)
|
88
|
-
all_data = Impl::Model.make_all_store_data(message[:data])
|
89
|
+
all_data = Impl::Model.make_all_store_data(message[:data], @config.logger)
|
89
90
|
@feature_store.init(all_data)
|
90
91
|
@initialized.make_true
|
91
92
|
@config.logger.info { "[LDClient] Stream initialized" }
|
@@ -95,9 +96,8 @@ module LaunchDarkly
|
|
95
96
|
for kind in [FEATURES, SEGMENTS]
|
96
97
|
key = key_for_path(kind, data[:path])
|
97
98
|
if key
|
98
|
-
|
99
|
-
|
100
|
-
@feature_store.upsert(kind, data)
|
99
|
+
item = Impl::Model.deserialize(kind, data[:data], @config.logger)
|
100
|
+
@feature_store.upsert(kind, item)
|
101
101
|
break
|
102
102
|
end
|
103
103
|
end
|
data/lib/ldclient-rb/util.rb
CHANGED
@@ -4,30 +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
|
13
|
+
unless proxy.nil?
|
14
|
+
http_client_options["proxy"] = {
|
15
|
+
proxy_address: proxy.host,
|
16
|
+
proxy_port: proxy.port,
|
17
|
+
proxy_username: proxy.user,
|
18
|
+
proxy_password: proxy.password,
|
19
|
+
}
|
20
|
+
end
|
21
|
+
HTTP::Client.new(http_client_options)
|
28
22
|
.timeout({
|
29
23
|
read: config.read_timeout,
|
30
|
-
connect: config.connect_timeout
|
24
|
+
connect: config.connect_timeout,
|
31
25
|
})
|
32
26
|
.persistent(uri_s)
|
33
27
|
end
|
data/lib/ldclient-rb/version.rb
CHANGED
data/lib/ldclient-rb.rb
CHANGED
@@ -15,14 +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
|
-
require "ldclient-rb/event_summarizer"
|
25
24
|
require "ldclient-rb/events"
|
26
25
|
require "ldclient-rb/requestor"
|
27
|
-
require "ldclient-rb/file_data_source"
|
28
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:
|
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
|
@@ -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
|
@@ -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
|
@@ -198,14 +212,14 @@ dependencies:
|
|
198
212
|
requirements:
|
199
213
|
- - '='
|
200
214
|
- !ruby/object:Gem::Version
|
201
|
-
version: 2.
|
215
|
+
version: 2.2.1
|
202
216
|
type: :runtime
|
203
217
|
prerelease: false
|
204
218
|
version_requirements: !ruby/object:Gem::Requirement
|
205
219
|
requirements:
|
206
220
|
- - '='
|
207
221
|
- !ruby/object:Gem::Version
|
208
|
-
version: 2.
|
222
|
+
version: 2.2.1
|
209
223
|
- !ruby/object:Gem::Dependency
|
210
224
|
name: json
|
211
225
|
requirement: !ruby/object:Gem::Requirement
|
@@ -253,23 +267,34 @@ 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
|
-
- lib/ldclient-rb/event_summarizer.rb
|
258
272
|
- lib/ldclient-rb/events.rb
|
259
273
|
- lib/ldclient-rb/expiring_cache.rb
|
260
|
-
- lib/ldclient-rb/file_data_source.rb
|
261
274
|
- lib/ldclient-rb/flags_state.rb
|
262
275
|
- lib/ldclient-rb/impl.rb
|
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
|
-
- lib/ldclient-rb/impl/event_factory.rb
|
268
284
|
- lib/ldclient-rb/impl/event_sender.rb
|
285
|
+
- lib/ldclient-rb/impl/event_summarizer.rb
|
286
|
+
- lib/ldclient-rb/impl/event_types.rb
|
269
287
|
- lib/ldclient-rb/impl/integrations/consul_impl.rb
|
270
288
|
- lib/ldclient-rb/impl/integrations/dynamodb_impl.rb
|
289
|
+
- lib/ldclient-rb/impl/integrations/file_data_source.rb
|
271
290
|
- lib/ldclient-rb/impl/integrations/redis_impl.rb
|
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
|
272
296
|
- lib/ldclient-rb/impl/model/serialization.rb
|
297
|
+
- lib/ldclient-rb/impl/repeating_task.rb
|
273
298
|
- lib/ldclient-rb/impl/store_client_wrapper.rb
|
274
299
|
- lib/ldclient-rb/impl/store_data_set_sorter.rb
|
275
300
|
- lib/ldclient-rb/impl/unbounded_pool.rb
|
@@ -278,19 +303,20 @@ files:
|
|
278
303
|
- lib/ldclient-rb/integrations.rb
|
279
304
|
- lib/ldclient-rb/integrations/consul.rb
|
280
305
|
- lib/ldclient-rb/integrations/dynamodb.rb
|
306
|
+
- lib/ldclient-rb/integrations/file_data.rb
|
281
307
|
- lib/ldclient-rb/integrations/redis.rb
|
308
|
+
- lib/ldclient-rb/integrations/test_data.rb
|
309
|
+
- lib/ldclient-rb/integrations/test_data/flag_builder.rb
|
282
310
|
- lib/ldclient-rb/integrations/util/store_wrapper.rb
|
283
311
|
- lib/ldclient-rb/interfaces.rb
|
284
312
|
- lib/ldclient-rb/ldclient.rb
|
285
313
|
- lib/ldclient-rb/memoized_value.rb
|
286
|
-
- lib/ldclient-rb/newrelic.rb
|
287
314
|
- lib/ldclient-rb/non_blocking_thread_pool.rb
|
288
315
|
- lib/ldclient-rb/polling.rb
|
289
|
-
- lib/ldclient-rb/
|
316
|
+
- lib/ldclient-rb/reference.rb
|
290
317
|
- lib/ldclient-rb/requestor.rb
|
291
318
|
- lib/ldclient-rb/simple_lru_cache.rb
|
292
319
|
- lib/ldclient-rb/stream.rb
|
293
|
-
- lib/ldclient-rb/user_filter.rb
|
294
320
|
- lib/ldclient-rb/util.rb
|
295
321
|
- lib/ldclient-rb/version.rb
|
296
322
|
homepage: https://github.com/launchdarkly/ruby-server-sdk
|
@@ -305,14 +331,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
305
331
|
requirements:
|
306
332
|
- - ">="
|
307
333
|
- !ruby/object:Gem::Version
|
308
|
-
version: 2.
|
334
|
+
version: 2.7.0
|
309
335
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
310
336
|
requirements:
|
311
337
|
- - ">="
|
312
338
|
- !ruby/object:Gem::Version
|
313
339
|
version: '0'
|
314
340
|
requirements: []
|
315
|
-
rubygems_version: 3.
|
341
|
+
rubygems_version: 3.4.1
|
316
342
|
signing_key:
|
317
343
|
specification_version: 4
|
318
344
|
summary: LaunchDarkly SDK for Ruby
|