launchdarkly-server-sdk 6.3.0 → 8.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 +3 -4
- data/lib/ldclient-rb/config.rb +112 -62
- data/lib/ldclient-rb/context.rb +444 -0
- data/lib/ldclient-rb/evaluation_detail.rb +26 -22
- data/lib/ldclient-rb/events.rb +256 -146
- data/lib/ldclient-rb/flags_state.rb +26 -15
- data/lib/ldclient-rb/impl/big_segments.rb +18 -18
- data/lib/ldclient-rb/impl/broadcaster.rb +78 -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/data_source.rb +188 -0
- data/lib/ldclient-rb/impl/data_store.rb +59 -0
- data/lib/ldclient-rb/impl/dependency_tracker.rb +102 -0
- data/lib/ldclient-rb/impl/diagnostic_events.rb +9 -10
- data/lib/ldclient-rb/impl/evaluator.rb +386 -142
- 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 +7 -6
- data/lib/ldclient-rb/impl/event_summarizer.rb +68 -0
- data/lib/ldclient-rb/impl/event_types.rb +136 -0
- data/lib/ldclient-rb/impl/flag_tracker.rb +58 -0
- data/lib/ldclient-rb/impl/integrations/consul_impl.rb +19 -7
- data/lib/ldclient-rb/impl/integrations/dynamodb_impl.rb +38 -30
- data/lib/ldclient-rb/impl/integrations/file_data_source.rb +24 -11
- data/lib/ldclient-rb/impl/integrations/redis_impl.rb +109 -12
- data/lib/ldclient-rb/impl/migrations/migrator.rb +287 -0
- data/lib/ldclient-rb/impl/migrations/tracker.rb +136 -0
- data/lib/ldclient-rb/impl/model/clause.rb +45 -0
- data/lib/ldclient-rb/impl/model/feature_flag.rb +255 -0
- data/lib/ldclient-rb/impl/model/preprocessed_data.rb +64 -0
- data/lib/ldclient-rb/impl/model/segment.rb +132 -0
- data/lib/ldclient-rb/impl/model/serialization.rb +54 -44
- data/lib/ldclient-rb/impl/repeating_task.rb +3 -4
- data/lib/ldclient-rb/impl/sampler.rb +25 -0
- data/lib/ldclient-rb/impl/store_client_wrapper.rb +102 -8
- 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 +9 -2
- data/lib/ldclient-rb/integrations/consul.rb +2 -2
- data/lib/ldclient-rb/integrations/dynamodb.rb +2 -2
- data/lib/ldclient-rb/integrations/file_data.rb +4 -4
- data/lib/ldclient-rb/integrations/redis.rb +5 -5
- data/lib/ldclient-rb/integrations/test_data/flag_builder.rb +287 -62
- data/lib/ldclient-rb/integrations/test_data.rb +18 -14
- data/lib/ldclient-rb/integrations/util/store_wrapper.rb +20 -9
- data/lib/ldclient-rb/interfaces.rb +600 -14
- data/lib/ldclient-rb/ldclient.rb +314 -134
- data/lib/ldclient-rb/memoized_value.rb +1 -1
- data/lib/ldclient-rb/migrations.rb +230 -0
- data/lib/ldclient-rb/non_blocking_thread_pool.rb +1 -1
- data/lib/ldclient-rb/polling.rb +52 -6
- data/lib/ldclient-rb/reference.rb +274 -0
- data/lib/ldclient-rb/requestor.rb +9 -11
- data/lib/ldclient-rb/stream.rb +96 -34
- data/lib/ldclient-rb/util.rb +97 -14
- data/lib/ldclient-rb/version.rb +1 -1
- data/lib/ldclient-rb.rb +3 -4
- metadata +65 -23
- data/lib/ldclient-rb/event_summarizer.rb +0 -55
- data/lib/ldclient-rb/file_data_source.rb +0 -23
- 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
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
|
@@ -25,6 +25,7 @@ module LaunchDarkly
|
|
25
25
|
def initialize(sdk_key, config, diagnostic_accumulator = nil)
|
26
26
|
@sdk_key = sdk_key
|
27
27
|
@config = config
|
28
|
+
@data_source_update_sink = config.data_source_update_sink
|
28
29
|
@feature_store = config.feature_store
|
29
30
|
@initialized = Concurrent::AtomicBoolean.new(false)
|
30
31
|
@started = Concurrent::AtomicBoolean.new(false)
|
@@ -41,77 +42,138 @@ module LaunchDarkly
|
|
41
42
|
return @ready unless @started.make_true
|
42
43
|
|
43
44
|
@config.logger.info { "[LDClient] Initializing stream connection" }
|
44
|
-
|
45
|
+
|
45
46
|
headers = Impl::Util.default_http_headers(@sdk_key, @config)
|
46
47
|
opts = {
|
47
48
|
headers: headers,
|
48
49
|
read_timeout: READ_TIMEOUT_SECONDS,
|
49
50
|
logger: @config.logger,
|
50
|
-
socket_factory: @config.socket_factory
|
51
|
+
socket_factory: @config.socket_factory,
|
52
|
+
reconnect_time: @config.initial_reconnect_delay,
|
51
53
|
}
|
52
54
|
log_connection_started
|
53
|
-
|
55
|
+
|
56
|
+
uri = Util.add_payload_filter_key(@config.stream_uri + "/all", @config)
|
57
|
+
@es = SSE::Client.new(uri, **opts) do |conn|
|
54
58
|
conn.on_event { |event| process_message(event) }
|
55
59
|
conn.on_error { |err|
|
56
60
|
log_connection_result(false)
|
57
61
|
case err
|
58
62
|
when SSE::Errors::HTTPStatusError
|
59
63
|
status = err.status
|
64
|
+
error_info = LaunchDarkly::Interfaces::DataSource::ErrorInfo.new(
|
65
|
+
LaunchDarkly::Interfaces::DataSource::ErrorInfo::ERROR_RESPONSE, status, nil, Time.now)
|
60
66
|
message = Util.http_error_message(status, "streaming connection", "will retry")
|
61
67
|
@config.logger.error { "[LDClient] #{message}" }
|
62
|
-
|
68
|
+
|
69
|
+
if Util.http_error_recoverable?(status)
|
70
|
+
@data_source_update_sink&.update_status(
|
71
|
+
LaunchDarkly::Interfaces::DataSource::Status::INTERRUPTED,
|
72
|
+
error_info
|
73
|
+
)
|
74
|
+
else
|
63
75
|
@ready.set # if client was waiting on us, make it stop waiting - has no effect if already set
|
64
|
-
|
76
|
+
stop_with_error_info error_info
|
65
77
|
end
|
78
|
+
when SSE::Errors::HTTPContentTypeError, SSE::Errors::HTTPProxyError, SSE::Errors::ReadTimeoutError
|
79
|
+
@data_source_update_sink&.update_status(
|
80
|
+
LaunchDarkly::Interfaces::DataSource::Status::INTERRUPTED,
|
81
|
+
LaunchDarkly::Interfaces::DataSource::ErrorInfo.new(LaunchDarkly::Interfaces::DataSource::ErrorInfo::NETWORK_ERROR, 0, err.to_s, Time.now)
|
82
|
+
)
|
83
|
+
|
84
|
+
else
|
85
|
+
@data_source_update_sink&.update_status(
|
86
|
+
LaunchDarkly::Interfaces::DataSource::Status::INTERRUPTED,
|
87
|
+
LaunchDarkly::Interfaces::DataSource::ErrorInfo.new(LaunchDarkly::Interfaces::DataSource::ErrorInfo::UNKNOWN, 0, err.to_s, Time.now)
|
88
|
+
)
|
66
89
|
end
|
67
90
|
}
|
68
91
|
end
|
69
|
-
|
92
|
+
|
70
93
|
@ready
|
71
94
|
end
|
72
95
|
|
73
96
|
def stop
|
97
|
+
stop_with_error_info
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
#
|
103
|
+
# @param [LaunchDarkly::Interfaces::DataSource::ErrorInfo, nil] error_info
|
104
|
+
#
|
105
|
+
def stop_with_error_info(error_info = nil)
|
74
106
|
if @stopped.make_true
|
75
107
|
@es.close
|
108
|
+
@data_source_update_sink&.update_status(LaunchDarkly::Interfaces::DataSource::Status::OFF, error_info)
|
76
109
|
@config.logger.info { "[LDClient] Stream connection stopped" }
|
77
110
|
end
|
78
111
|
end
|
79
112
|
|
80
|
-
|
113
|
+
#
|
114
|
+
# The original implementation of this class relied on the feature store
|
115
|
+
# directly, which we are trying to move away from. Customers who might have
|
116
|
+
# instantiated this directly for some reason wouldn't know they have to set
|
117
|
+
# the config's sink manually, so we have to fall back to the store if the
|
118
|
+
# sink isn't present.
|
119
|
+
#
|
120
|
+
# The next major release should be able to simplify this structure and
|
121
|
+
# remove the need for fall back to the data store because the update sink
|
122
|
+
# should always be present.
|
123
|
+
#
|
124
|
+
def update_sink_or_data_store
|
125
|
+
@data_source_update_sink || @feature_store
|
126
|
+
end
|
81
127
|
|
82
128
|
def process_message(message)
|
83
129
|
log_connection_result(true)
|
84
130
|
method = message.type
|
85
131
|
@config.logger.debug { "[LDClient] Stream received #{method} message: #{message.data}" }
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
132
|
+
|
133
|
+
begin
|
134
|
+
if method == PUT
|
135
|
+
message = JSON.parse(message.data, symbolize_names: true)
|
136
|
+
all_data = Impl::Model.make_all_store_data(message[:data], @config.logger)
|
137
|
+
update_sink_or_data_store.init(all_data)
|
138
|
+
@initialized.make_true
|
139
|
+
@config.logger.info { "[LDClient] Stream initialized" }
|
140
|
+
@ready.set
|
141
|
+
elsif method == PATCH
|
142
|
+
data = JSON.parse(message.data, symbolize_names: true)
|
143
|
+
for kind in [FEATURES, SEGMENTS]
|
144
|
+
key = key_for_path(kind, data[:path])
|
145
|
+
if key
|
146
|
+
item = Impl::Model.deserialize(kind, data[:data], @config.logger)
|
147
|
+
update_sink_or_data_store.upsert(kind, item)
|
148
|
+
break
|
149
|
+
end
|
102
150
|
end
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
151
|
+
elsif method == DELETE
|
152
|
+
data = JSON.parse(message.data, symbolize_names: true)
|
153
|
+
for kind in [FEATURES, SEGMENTS]
|
154
|
+
key = key_for_path(kind, data[:path])
|
155
|
+
if key
|
156
|
+
update_sink_or_data_store.delete(kind, key, data[:version])
|
157
|
+
break
|
158
|
+
end
|
111
159
|
end
|
160
|
+
else
|
161
|
+
@config.logger.warn { "[LDClient] Unknown message received: #{method}" }
|
112
162
|
end
|
113
|
-
|
114
|
-
@
|
163
|
+
|
164
|
+
@data_source_update_sink&.update_status(LaunchDarkly::Interfaces::DataSource::Status::VALID, nil)
|
165
|
+
rescue JSON::ParserError => e
|
166
|
+
@config.logger.error { "[LDClient] JSON parsing failed for method #{method}. Ignoring event." }
|
167
|
+
error_info = LaunchDarkly::Interfaces::DataSource::ErrorInfo.new(
|
168
|
+
LaunchDarkly::Interfaces::DataSource::ErrorInfo::INVALID_DATA,
|
169
|
+
0,
|
170
|
+
e.to_s,
|
171
|
+
Time.now
|
172
|
+
)
|
173
|
+
@data_source_update_sink&.update_status(LaunchDarkly::Interfaces::DataSource::Status::INTERRUPTED, error_info)
|
174
|
+
|
175
|
+
# Re-raise the exception so the SSE implementation can catch it and restart the stream.
|
176
|
+
raise
|
115
177
|
end
|
116
178
|
end
|
117
179
|
|
data/lib/ldclient-rb/util.rb
CHANGED
@@ -2,21 +2,95 @@ require "uri"
|
|
2
2
|
require "http"
|
3
3
|
|
4
4
|
module LaunchDarkly
|
5
|
+
#
|
6
|
+
# A Result is used to reflect the outcome of any operation.
|
7
|
+
#
|
8
|
+
# Results can either be considered a success or a failure.
|
9
|
+
#
|
10
|
+
# In the event of success, the Result will contain an option, nullable value to hold any success value back to the
|
11
|
+
# calling function.
|
12
|
+
#
|
13
|
+
# If the operation fails, the Result will contain an error describing the value.
|
14
|
+
#
|
15
|
+
class Result
|
16
|
+
#
|
17
|
+
# Create a successful result with the provided value.
|
18
|
+
#
|
19
|
+
# @param value [Object, nil]
|
20
|
+
# @return [Result]
|
21
|
+
#
|
22
|
+
def self.success(value)
|
23
|
+
Result.new(value)
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Create a failed result with the provided error description.
|
28
|
+
#
|
29
|
+
# @param error [String]
|
30
|
+
# @param exception [Exception, nil]
|
31
|
+
# @return [Result]
|
32
|
+
#
|
33
|
+
def self.fail(error, exception = nil)
|
34
|
+
Result.new(nil, error, exception)
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# Was this result successful or did it encounter an error?
|
39
|
+
#
|
40
|
+
# @return [Boolean]
|
41
|
+
#
|
42
|
+
def success?
|
43
|
+
@error.nil?
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# @return [Object, nil] The value returned from the operation if it was successful; nil otherwise.
|
48
|
+
#
|
49
|
+
attr_reader :value
|
50
|
+
|
51
|
+
#
|
52
|
+
# @return [String, nil] An error description of the failure; nil otherwise
|
53
|
+
#
|
54
|
+
attr_reader :error
|
55
|
+
|
56
|
+
#
|
57
|
+
# @return [Exception, nil] An optional exception which caused the failure
|
58
|
+
#
|
59
|
+
attr_reader :exception
|
60
|
+
|
61
|
+
private def initialize(value, error = nil, exception = nil)
|
62
|
+
@value = value
|
63
|
+
@error = error
|
64
|
+
@exception = exception
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
5
68
|
# @private
|
6
69
|
module Util
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
70
|
+
#
|
71
|
+
# Append the payload filter key query parameter to the provided URI.
|
72
|
+
#
|
73
|
+
# @param uri [String]
|
74
|
+
# @param config [Config]
|
75
|
+
# @return [String]
|
76
|
+
#
|
77
|
+
def self.add_payload_filter_key(uri, config)
|
78
|
+
return uri if config.payload_filter_key.nil?
|
79
|
+
|
80
|
+
unless config.payload_filter_key.is_a?(String) && !config.payload_filter_key.empty?
|
81
|
+
config.logger.warn { "[LDClient] Filter key must be a non-empty string. No filtering will be applied." }
|
82
|
+
return uri
|
83
|
+
end
|
84
|
+
|
85
|
+
begin
|
86
|
+
parsed = URI.parse(uri)
|
87
|
+
new_query_params = URI.decode_www_form(String(parsed.query)) << ["filter", config.payload_filter_key]
|
88
|
+
parsed.query = URI.encode_www_form(new_query_params)
|
89
|
+
parsed.to_s
|
90
|
+
rescue URI::InvalidURIError
|
91
|
+
config.logger.warn { "[LDClient] URI could not be parsed. No filtering will be applied." }
|
92
|
+
uri
|
18
93
|
end
|
19
|
-
ret
|
20
94
|
end
|
21
95
|
|
22
96
|
def self.new_http_client(uri_s, config)
|
@@ -24,10 +98,19 @@ module LaunchDarkly
|
|
24
98
|
if config.socket_factory
|
25
99
|
http_client_options["socket_class"] = config.socket_factory
|
26
100
|
end
|
27
|
-
|
101
|
+
proxy = URI.parse(uri_s).find_proxy
|
102
|
+
unless proxy.nil?
|
103
|
+
http_client_options["proxy"] = {
|
104
|
+
proxy_address: proxy.host,
|
105
|
+
proxy_port: proxy.port,
|
106
|
+
proxy_username: proxy.user,
|
107
|
+
proxy_password: proxy.password,
|
108
|
+
}
|
109
|
+
end
|
110
|
+
HTTP::Client.new(http_client_options)
|
28
111
|
.timeout({
|
29
112
|
read: config.read_timeout,
|
30
|
-
connect: config.connect_timeout
|
113
|
+
connect: config.connect_timeout,
|
31
114
|
})
|
32
115
|
.persistent(uri_s)
|
33
116
|
end
|
data/lib/ldclient-rb/version.rb
CHANGED
data/lib/ldclient-rb.rb
CHANGED
@@ -9,20 +9,19 @@ require "ldclient-rb/version"
|
|
9
9
|
require "ldclient-rb/interfaces"
|
10
10
|
require "ldclient-rb/util"
|
11
11
|
require "ldclient-rb/flags_state"
|
12
|
+
require "ldclient-rb/migrations"
|
12
13
|
require "ldclient-rb/ldclient"
|
13
14
|
require "ldclient-rb/cache_store"
|
14
15
|
require "ldclient-rb/expiring_cache"
|
15
16
|
require "ldclient-rb/memoized_value"
|
16
17
|
require "ldclient-rb/in_memory_store"
|
17
18
|
require "ldclient-rb/config"
|
18
|
-
require "ldclient-rb/
|
19
|
+
require "ldclient-rb/context"
|
20
|
+
require "ldclient-rb/reference"
|
19
21
|
require "ldclient-rb/stream"
|
20
22
|
require "ldclient-rb/polling"
|
21
|
-
require "ldclient-rb/user_filter"
|
22
23
|
require "ldclient-rb/simple_lru_cache"
|
23
24
|
require "ldclient-rb/non_blocking_thread_pool"
|
24
|
-
require "ldclient-rb/event_summarizer"
|
25
25
|
require "ldclient-rb/events"
|
26
26
|
require "ldclient-rb/requestor"
|
27
|
-
require "ldclient-rb/file_data_source"
|
28
27
|
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: 8.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: 2023-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-dynamodb
|
@@ -30,14 +30,28 @@ 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
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: simplecov
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.21'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.21'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rspec
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,42 +72,42 @@ dependencies:
|
|
58
72
|
requirements:
|
59
73
|
- - "~>"
|
60
74
|
- !ruby/object:Gem::Version
|
61
|
-
version: 2.
|
75
|
+
version: '2.6'
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
80
|
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version: 2.
|
82
|
+
version: '2.6'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: redis
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - "~>"
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
89
|
+
version: '5.0'
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
94
|
- - "~>"
|
81
95
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
96
|
+
version: '5.0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: connection_pool
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
101
|
- - "~>"
|
88
102
|
- !ruby/object:Gem::Version
|
89
|
-
version: 2.
|
103
|
+
version: '2.3'
|
90
104
|
type: :development
|
91
105
|
prerelease: false
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
93
107
|
requirements:
|
94
108
|
- - "~>"
|
95
109
|
- !ruby/object:Gem::Version
|
96
|
-
version: 2.
|
110
|
+
version: '2.3'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: rspec_junit_formatter
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -151,19 +165,33 @@ dependencies:
|
|
151
165
|
- !ruby/object:Gem::Version
|
152
166
|
version: '1.7'
|
153
167
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
168
|
+
name: rubocop
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '1.37'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '1.37'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: rubocop-performance
|
155
183
|
requirement: !ruby/object:Gem::Requirement
|
156
184
|
requirements:
|
157
185
|
- - "~>"
|
158
186
|
- !ruby/object:Gem::Version
|
159
|
-
version: '
|
187
|
+
version: '1.15'
|
160
188
|
type: :development
|
161
189
|
prerelease: false
|
162
190
|
version_requirements: !ruby/object:Gem::Requirement
|
163
191
|
requirements:
|
164
192
|
- - "~>"
|
165
193
|
- !ruby/object:Gem::Version
|
166
|
-
version: '
|
194
|
+
version: '1.15'
|
167
195
|
- !ruby/object:Gem::Dependency
|
168
196
|
name: semantic
|
169
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -198,14 +226,14 @@ dependencies:
|
|
198
226
|
requirements:
|
199
227
|
- - '='
|
200
228
|
- !ruby/object:Gem::Version
|
201
|
-
version: 2.
|
229
|
+
version: 2.2.2
|
202
230
|
type: :runtime
|
203
231
|
prerelease: false
|
204
232
|
version_requirements: !ruby/object:Gem::Requirement
|
205
233
|
requirements:
|
206
234
|
- - '='
|
207
235
|
- !ruby/object:Gem::Version
|
208
|
-
version: 2.
|
236
|
+
version: 2.2.2
|
209
237
|
- !ruby/object:Gem::Dependency
|
210
238
|
name: json
|
211
239
|
requirement: !ruby/object:Gem::Requirement
|
@@ -253,27 +281,42 @@ files:
|
|
253
281
|
- lib/ldclient-rb.rb
|
254
282
|
- lib/ldclient-rb/cache_store.rb
|
255
283
|
- lib/ldclient-rb/config.rb
|
284
|
+
- lib/ldclient-rb/context.rb
|
256
285
|
- lib/ldclient-rb/evaluation_detail.rb
|
257
|
-
- lib/ldclient-rb/event_summarizer.rb
|
258
286
|
- lib/ldclient-rb/events.rb
|
259
287
|
- lib/ldclient-rb/expiring_cache.rb
|
260
|
-
- lib/ldclient-rb/file_data_source.rb
|
261
288
|
- lib/ldclient-rb/flags_state.rb
|
262
289
|
- lib/ldclient-rb/impl.rb
|
263
290
|
- lib/ldclient-rb/impl/big_segments.rb
|
291
|
+
- lib/ldclient-rb/impl/broadcaster.rb
|
292
|
+
- lib/ldclient-rb/impl/context.rb
|
293
|
+
- lib/ldclient-rb/impl/context_filter.rb
|
294
|
+
- lib/ldclient-rb/impl/data_source.rb
|
295
|
+
- lib/ldclient-rb/impl/data_store.rb
|
296
|
+
- lib/ldclient-rb/impl/dependency_tracker.rb
|
264
297
|
- lib/ldclient-rb/impl/diagnostic_events.rb
|
265
298
|
- lib/ldclient-rb/impl/evaluator.rb
|
266
299
|
- lib/ldclient-rb/impl/evaluator_bucketing.rb
|
300
|
+
- lib/ldclient-rb/impl/evaluator_helpers.rb
|
267
301
|
- lib/ldclient-rb/impl/evaluator_operators.rb
|
268
|
-
- lib/ldclient-rb/impl/event_factory.rb
|
269
302
|
- lib/ldclient-rb/impl/event_sender.rb
|
303
|
+
- lib/ldclient-rb/impl/event_summarizer.rb
|
304
|
+
- lib/ldclient-rb/impl/event_types.rb
|
305
|
+
- lib/ldclient-rb/impl/flag_tracker.rb
|
270
306
|
- lib/ldclient-rb/impl/integrations/consul_impl.rb
|
271
307
|
- lib/ldclient-rb/impl/integrations/dynamodb_impl.rb
|
272
308
|
- lib/ldclient-rb/impl/integrations/file_data_source.rb
|
273
309
|
- lib/ldclient-rb/impl/integrations/redis_impl.rb
|
274
310
|
- lib/ldclient-rb/impl/integrations/test_data/test_data_source.rb
|
311
|
+
- lib/ldclient-rb/impl/migrations/migrator.rb
|
312
|
+
- lib/ldclient-rb/impl/migrations/tracker.rb
|
313
|
+
- lib/ldclient-rb/impl/model/clause.rb
|
314
|
+
- lib/ldclient-rb/impl/model/feature_flag.rb
|
315
|
+
- lib/ldclient-rb/impl/model/preprocessed_data.rb
|
316
|
+
- lib/ldclient-rb/impl/model/segment.rb
|
275
317
|
- lib/ldclient-rb/impl/model/serialization.rb
|
276
318
|
- lib/ldclient-rb/impl/repeating_task.rb
|
319
|
+
- lib/ldclient-rb/impl/sampler.rb
|
277
320
|
- lib/ldclient-rb/impl/store_client_wrapper.rb
|
278
321
|
- lib/ldclient-rb/impl/store_data_set_sorter.rb
|
279
322
|
- lib/ldclient-rb/impl/unbounded_pool.rb
|
@@ -290,14 +333,13 @@ files:
|
|
290
333
|
- lib/ldclient-rb/interfaces.rb
|
291
334
|
- lib/ldclient-rb/ldclient.rb
|
292
335
|
- lib/ldclient-rb/memoized_value.rb
|
293
|
-
- lib/ldclient-rb/
|
336
|
+
- lib/ldclient-rb/migrations.rb
|
294
337
|
- lib/ldclient-rb/non_blocking_thread_pool.rb
|
295
338
|
- lib/ldclient-rb/polling.rb
|
296
|
-
- lib/ldclient-rb/
|
339
|
+
- lib/ldclient-rb/reference.rb
|
297
340
|
- lib/ldclient-rb/requestor.rb
|
298
341
|
- lib/ldclient-rb/simple_lru_cache.rb
|
299
342
|
- lib/ldclient-rb/stream.rb
|
300
|
-
- lib/ldclient-rb/user_filter.rb
|
301
343
|
- lib/ldclient-rb/util.rb
|
302
344
|
- lib/ldclient-rb/version.rb
|
303
345
|
homepage: https://github.com/launchdarkly/ruby-server-sdk
|
@@ -312,14 +354,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
312
354
|
requirements:
|
313
355
|
- - ">="
|
314
356
|
- !ruby/object:Gem::Version
|
315
|
-
version:
|
357
|
+
version: 3.0.0
|
316
358
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
317
359
|
requirements:
|
318
360
|
- - ">="
|
319
361
|
- !ruby/object:Gem::Version
|
320
362
|
version: '0'
|
321
363
|
requirements: []
|
322
|
-
rubygems_version: 3.
|
364
|
+
rubygems_version: 3.4.21
|
323
365
|
signing_key:
|
324
366
|
specification_version: 4
|
325
367
|
summary: LaunchDarkly SDK for Ruby
|
@@ -1,55 +0,0 @@
|
|
1
|
-
|
2
|
-
module LaunchDarkly
|
3
|
-
# @private
|
4
|
-
EventSummary = Struct.new(:start_date, :end_date, :counters)
|
5
|
-
|
6
|
-
# Manages the state of summarizable information for the EventProcessor, including the
|
7
|
-
# event counters and user deduplication. Note that the methods of this class are
|
8
|
-
# deliberately not thread-safe; the EventProcessor is responsible for enforcing
|
9
|
-
# synchronization across both the summarizer and the event queue.
|
10
|
-
#
|
11
|
-
# @private
|
12
|
-
class EventSummarizer
|
13
|
-
def initialize
|
14
|
-
clear
|
15
|
-
end
|
16
|
-
|
17
|
-
# Adds this event to our counters, if it is a type of event we need to count.
|
18
|
-
def summarize_event(event)
|
19
|
-
if event[:kind] == "feature"
|
20
|
-
counter_key = {
|
21
|
-
key: event[:key],
|
22
|
-
version: event[:version],
|
23
|
-
variation: event[:variation]
|
24
|
-
}
|
25
|
-
c = @counters[counter_key]
|
26
|
-
if c.nil?
|
27
|
-
@counters[counter_key] = {
|
28
|
-
value: event[:value],
|
29
|
-
default: event[:default],
|
30
|
-
count: 1
|
31
|
-
}
|
32
|
-
else
|
33
|
-
c[:count] = c[:count] + 1
|
34
|
-
end
|
35
|
-
time = event[:creationDate]
|
36
|
-
if !time.nil?
|
37
|
-
@start_date = time if @start_date == 0 || time < @start_date
|
38
|
-
@end_date = time if time > @end_date
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# Returns a snapshot of the current summarized event data, and resets this state.
|
44
|
-
def snapshot
|
45
|
-
ret = EventSummary.new(@start_date, @end_date, @counters)
|
46
|
-
ret
|
47
|
-
end
|
48
|
-
|
49
|
-
def clear
|
50
|
-
@start_date = 0
|
51
|
-
@end_date = 0
|
52
|
-
@counters = {}
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -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
|