launchdarkly-server-sdk 6.2.2 → 6.3.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 -3
- data/lib/ldclient-rb/config.rb +81 -4
- data/lib/ldclient-rb/evaluation_detail.rb +67 -8
- data/lib/ldclient-rb/file_data_source.rb +9 -300
- data/lib/ldclient-rb/impl/big_segments.rb +117 -0
- data/lib/ldclient-rb/impl/diagnostic_events.rb +1 -1
- data/lib/ldclient-rb/impl/evaluator.rb +80 -28
- data/lib/ldclient-rb/impl/integrations/dynamodb_impl.rb +82 -18
- data/lib/ldclient-rb/impl/integrations/file_data_source.rb +212 -0
- data/lib/ldclient-rb/impl/integrations/redis_impl.rb +84 -31
- data/lib/ldclient-rb/impl/integrations/test_data/test_data_source.rb +40 -0
- data/lib/ldclient-rb/impl/repeating_task.rb +47 -0
- data/lib/ldclient-rb/impl/util.rb +4 -1
- data/lib/ldclient-rb/integrations/consul.rb +7 -0
- 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 +41 -1
- data/lib/ldclient-rb/integrations/test_data/flag_builder.rb +438 -0
- data/lib/ldclient-rb/integrations/test_data.rb +209 -0
- data/lib/ldclient-rb/integrations/util/store_wrapper.rb +5 -0
- data/lib/ldclient-rb/integrations.rb +2 -51
- data/lib/ldclient-rb/interfaces.rb +152 -2
- data/lib/ldclient-rb/ldclient.rb +21 -7
- data/lib/ldclient-rb/polling.rb +22 -41
- data/lib/ldclient-rb/util.rb +1 -1
- data/lib/ldclient-rb/version.rb +1 -1
- metadata +31 -132
- data/.circleci/config.yml +0 -40
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -37
- data/.github/ISSUE_TEMPLATE/config.yml +0 -5
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
- data/.github/pull_request_template.md +0 -21
- data/.gitignore +0 -16
- data/.hound.yml +0 -2
- data/.ldrelease/build-docs.sh +0 -18
- data/.ldrelease/circleci/linux/execute.sh +0 -18
- data/.ldrelease/circleci/mac/execute.sh +0 -18
- data/.ldrelease/circleci/template/build.sh +0 -29
- data/.ldrelease/circleci/template/publish.sh +0 -23
- data/.ldrelease/circleci/template/set-gem-home.sh +0 -7
- data/.ldrelease/circleci/template/test.sh +0 -10
- data/.ldrelease/circleci/template/update-version.sh +0 -8
- data/.ldrelease/circleci/windows/execute.ps1 +0 -19
- data/.ldrelease/config.yml +0 -29
- data/.rspec +0 -2
- data/.rubocop.yml +0 -600
- data/.simplecov +0 -4
- data/CHANGELOG.md +0 -363
- data/CODEOWNERS +0 -1
- data/CONTRIBUTING.md +0 -37
- data/Gemfile +0 -3
- data/azure-pipelines.yml +0 -51
- data/docs/Makefile +0 -26
- data/docs/index.md +0 -9
- data/launchdarkly-server-sdk.gemspec +0 -45
- data/spec/config_spec.rb +0 -63
- data/spec/diagnostic_events_spec.rb +0 -163
- data/spec/evaluation_detail_spec.rb +0 -135
- data/spec/event_sender_spec.rb +0 -197
- data/spec/event_summarizer_spec.rb +0 -63
- data/spec/events_spec.rb +0 -607
- data/spec/expiring_cache_spec.rb +0 -76
- data/spec/feature_store_spec_base.rb +0 -213
- data/spec/file_data_source_spec.rb +0 -283
- data/spec/fixtures/feature.json +0 -37
- data/spec/fixtures/feature1.json +0 -36
- data/spec/fixtures/user.json +0 -9
- data/spec/flags_state_spec.rb +0 -81
- data/spec/http_util.rb +0 -132
- data/spec/impl/evaluator_bucketing_spec.rb +0 -216
- data/spec/impl/evaluator_clause_spec.rb +0 -55
- data/spec/impl/evaluator_operators_spec.rb +0 -141
- data/spec/impl/evaluator_rule_spec.rb +0 -128
- data/spec/impl/evaluator_segment_spec.rb +0 -125
- data/spec/impl/evaluator_spec.rb +0 -349
- data/spec/impl/evaluator_spec_base.rb +0 -75
- data/spec/impl/event_factory_spec.rb +0 -108
- data/spec/impl/model/serialization_spec.rb +0 -41
- data/spec/in_memory_feature_store_spec.rb +0 -12
- data/spec/integrations/consul_feature_store_spec.rb +0 -40
- data/spec/integrations/dynamodb_feature_store_spec.rb +0 -103
- data/spec/integrations/store_wrapper_spec.rb +0 -276
- data/spec/launchdarkly-server-sdk_spec.rb +0 -13
- data/spec/launchdarkly-server-sdk_spec_autoloadtest.rb +0 -9
- data/spec/ldclient_end_to_end_spec.rb +0 -157
- data/spec/ldclient_spec.rb +0 -635
- data/spec/newrelic_spec.rb +0 -5
- data/spec/polling_spec.rb +0 -120
- data/spec/redis_feature_store_spec.rb +0 -121
- data/spec/requestor_spec.rb +0 -209
- data/spec/segment_store_spec_base.rb +0 -95
- data/spec/simple_lru_cache_spec.rb +0 -24
- data/spec/spec_helper.rb +0 -9
- data/spec/store_spec.rb +0 -10
- data/spec/stream_spec.rb +0 -45
- data/spec/user_filter_spec.rb +0 -91
- data/spec/util_spec.rb +0 -17
- data/spec/version_spec.rb +0 -7
@@ -1,55 +1,6 @@
|
|
1
1
|
require "ldclient-rb/integrations/consul"
|
2
2
|
require "ldclient-rb/integrations/dynamodb"
|
3
|
+
require "ldclient-rb/integrations/file_data"
|
3
4
|
require "ldclient-rb/integrations/redis"
|
5
|
+
require "ldclient-rb/integrations/test_data"
|
4
6
|
require "ldclient-rb/integrations/util/store_wrapper"
|
5
|
-
|
6
|
-
module LaunchDarkly
|
7
|
-
#
|
8
|
-
# Tools for connecting the LaunchDarkly client to other software.
|
9
|
-
#
|
10
|
-
module Integrations
|
11
|
-
#
|
12
|
-
# Integration with [Consul](https://www.consul.io/).
|
13
|
-
#
|
14
|
-
# Note that in order to use this integration, you must first install the gem `diplomat`.
|
15
|
-
#
|
16
|
-
# @since 5.5.0
|
17
|
-
#
|
18
|
-
module Consul
|
19
|
-
# code is in ldclient-rb/impl/integrations/consul_impl
|
20
|
-
end
|
21
|
-
|
22
|
-
#
|
23
|
-
# Integration with [DynamoDB](https://aws.amazon.com/dynamodb/).
|
24
|
-
#
|
25
|
-
# Note that in order to use this integration, you must first install one of the AWS SDK gems: either
|
26
|
-
# `aws-sdk-dynamodb`, or the full `aws-sdk`.
|
27
|
-
#
|
28
|
-
# @since 5.5.0
|
29
|
-
#
|
30
|
-
module DynamoDB
|
31
|
-
# code is in ldclient-rb/impl/integrations/dynamodb_impl
|
32
|
-
end
|
33
|
-
|
34
|
-
#
|
35
|
-
# Integration with [Redis](https://redis.io/).
|
36
|
-
#
|
37
|
-
# Note that in order to use this integration, you must first install the `redis` and `connection-pool`
|
38
|
-
# gems.
|
39
|
-
#
|
40
|
-
# @since 5.5.0
|
41
|
-
#
|
42
|
-
module Redis
|
43
|
-
# code is in ldclient-rb/impl/integrations/redis_impl
|
44
|
-
end
|
45
|
-
|
46
|
-
#
|
47
|
-
# Support code that may be helpful in creating integrations.
|
48
|
-
#
|
49
|
-
# @since 5.5.0
|
50
|
-
#
|
51
|
-
module Util
|
52
|
-
# code is in ldclient-rb/integrations/util/
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require "observer"
|
1
2
|
|
2
3
|
module LaunchDarkly
|
3
4
|
#
|
@@ -9,7 +10,7 @@ module LaunchDarkly
|
|
9
10
|
# client uses the feature store to persist feature flags and related objects received from
|
10
11
|
# the LaunchDarkly service. Implementations must support concurrent access and updates.
|
11
12
|
# For more about how feature stores can be used, see:
|
12
|
-
# [Using a persistent feature store](https://docs.launchdarkly.com/
|
13
|
+
# [Using a persistent feature store](https://docs.launchdarkly.com/sdk/features/storing-data#ruby).
|
13
14
|
#
|
14
15
|
# An entity that can be stored in a feature store is a hash that can be converted to and from
|
15
16
|
# JSON, and that has at a minimum the following properties: `:key`, a string that is unique
|
@@ -120,7 +121,8 @@ module LaunchDarkly
|
|
120
121
|
#
|
121
122
|
# The client has its own standard implementation, which uses either a streaming connection or
|
122
123
|
# polling depending on your configuration. Normally you will not need to use another one
|
123
|
-
# except for testing purposes.
|
124
|
+
# except for testing purposes. Two such test fixtures are {LaunchDarkly::Integrations::FileData}
|
125
|
+
# and {LaunchDarkly::Integrations::TestData}.
|
124
126
|
#
|
125
127
|
module DataSource
|
126
128
|
#
|
@@ -149,5 +151,153 @@ module LaunchDarkly
|
|
149
151
|
def stop
|
150
152
|
end
|
151
153
|
end
|
154
|
+
|
155
|
+
module BigSegmentStore
|
156
|
+
#
|
157
|
+
# Returns information about the overall state of the store. This method will be called only
|
158
|
+
# when the SDK needs the latest state, so it should not be cached.
|
159
|
+
#
|
160
|
+
# @return [BigSegmentStoreMetadata]
|
161
|
+
#
|
162
|
+
def get_metadata
|
163
|
+
end
|
164
|
+
|
165
|
+
#
|
166
|
+
# Queries the store for a snapshot of the current segment state for a specific user.
|
167
|
+
#
|
168
|
+
# The user_hash is a base64-encoded string produced by hashing the user key as defined by
|
169
|
+
# the Big Segments specification; the store implementation does not need to know the details
|
170
|
+
# of how this is done, because it deals only with already-hashed keys, but the string can be
|
171
|
+
# assumed to only contain characters that are valid in base64.
|
172
|
+
#
|
173
|
+
# The return value should be either a Hash, or nil if the user is not referenced in any big
|
174
|
+
# segments. Each key in the Hash is a "segment reference", which is how segments are
|
175
|
+
# identified in Big Segment data. This string is not identical to the segment key-- the SDK
|
176
|
+
# will add other information. The store implementation should not be concerned with the
|
177
|
+
# format of the string. Each value in the Hash is true if the user is explicitly included in
|
178
|
+
# the segment, false if the user is explicitly excluded from the segment-- and is not also
|
179
|
+
# explicitly included (that is, if both an include and an exclude existed in the data, the
|
180
|
+
# include would take precedence). If the user's status in a particular segment is undefined,
|
181
|
+
# there should be no key or value for that segment.
|
182
|
+
#
|
183
|
+
# This Hash may be cached by the SDK, so it should not be modified after it is created. It
|
184
|
+
# is a snapshot of the segment membership state at one point in time.
|
185
|
+
#
|
186
|
+
# @param user_hash [String]
|
187
|
+
# @return [Hash] true/false values for Big Segments that reference this user
|
188
|
+
#
|
189
|
+
def get_membership(user_hash)
|
190
|
+
end
|
191
|
+
|
192
|
+
#
|
193
|
+
# Performs any necessary cleanup to shut down the store when the client is being shut down.
|
194
|
+
#
|
195
|
+
# @return [void]
|
196
|
+
#
|
197
|
+
def stop
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
#
|
202
|
+
# Values returned by {BigSegmentStore#get_metadata}.
|
203
|
+
#
|
204
|
+
class BigSegmentStoreMetadata
|
205
|
+
def initialize(last_up_to_date)
|
206
|
+
@last_up_to_date = last_up_to_date
|
207
|
+
end
|
208
|
+
|
209
|
+
# The Unix epoch millisecond timestamp of the last update to the {BigSegmentStore}. It is
|
210
|
+
# nil if the store has never been updated.
|
211
|
+
#
|
212
|
+
# @return [Integer|nil]
|
213
|
+
attr_reader :last_up_to_date
|
214
|
+
end
|
215
|
+
|
216
|
+
#
|
217
|
+
# Information about the status of a Big Segment store, provided by {BigSegmentStoreStatusProvider}.
|
218
|
+
#
|
219
|
+
# Big Segments are a specific type of user segments. For more information, read the LaunchDarkly
|
220
|
+
# documentation: https://docs.launchdarkly.com/home/users/big-segments
|
221
|
+
#
|
222
|
+
class BigSegmentStoreStatus
|
223
|
+
def initialize(available, stale)
|
224
|
+
@available = available
|
225
|
+
@stale = stale
|
226
|
+
end
|
227
|
+
|
228
|
+
# True if the Big Segment store is able to respond to queries, so that the SDK can evaluate
|
229
|
+
# whether a user is in a segment or not.
|
230
|
+
#
|
231
|
+
# If this property is false, the store is not able to make queries (for instance, it may not have
|
232
|
+
# a valid database connection). In this case, the SDK will treat any reference to a Big Segment
|
233
|
+
# as if no users are included in that segment. Also, the {EvaluationReason} associated with
|
234
|
+
# with any flag evaluation that references a Big Segment when the store is not available will
|
235
|
+
# have a `big_segments_status` of `STORE_ERROR`.
|
236
|
+
#
|
237
|
+
# @return [Boolean]
|
238
|
+
attr_reader :available
|
239
|
+
|
240
|
+
# True if the Big Segment store is available, but has not been updated within the amount of time
|
241
|
+
# specified by {BigSegmentsConfig#stale_after}.
|
242
|
+
#
|
243
|
+
# This may indicate that the LaunchDarkly Relay Proxy, which populates the store, has stopped
|
244
|
+
# running or has become unable to receive fresh data from LaunchDarkly. Any feature flag
|
245
|
+
# evaluations that reference a Big Segment will be using the last known data, which may be out
|
246
|
+
# of date. Also, the {EvaluationReason} associated with those evaluations will have a
|
247
|
+
# `big_segments_status` of `STALE`.
|
248
|
+
#
|
249
|
+
# @return [Boolean]
|
250
|
+
attr_reader :stale
|
251
|
+
|
252
|
+
def ==(other)
|
253
|
+
self.available == other.available && self.stale == other.stale
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
#
|
258
|
+
# An interface for querying the status of a Big Segment store.
|
259
|
+
#
|
260
|
+
# The Big Segment store is the component that receives information about Big Segments, normally
|
261
|
+
# from a database populated by the LaunchDarkly Relay Proxy. Big Segments are a specific type
|
262
|
+
# of user segments. For more information, read the LaunchDarkly documentation:
|
263
|
+
# https://docs.launchdarkly.com/home/users/big-segments
|
264
|
+
#
|
265
|
+
# An implementation of this interface is returned by {LDClient#big_segment_store_status_provider}.
|
266
|
+
# Application code never needs to implement this interface.
|
267
|
+
#
|
268
|
+
# There are two ways to interact with the status. One is to simply get the current status; if its
|
269
|
+
# `available` property is true, then the SDK is able to evaluate user membership in Big Segments,
|
270
|
+
# and the `stale`` property indicates whether the data might be out of date.
|
271
|
+
#
|
272
|
+
# The other way is to subscribe to status change notifications. Applications may wish to know if
|
273
|
+
# there is an outage in the Big Segment store, or if it has become stale (the Relay Proxy has
|
274
|
+
# stopped updating it with new data), since then flag evaluations that reference a Big Segment
|
275
|
+
# might return incorrect values. To allow finding out about status changes as soon as possible,
|
276
|
+
# `BigSegmentStoreStatusProvider` mixes in Ruby's
|
277
|
+
# [Observable](https://docs.ruby-lang.org/en/2.5.0/Observable.html) module to provide standard
|
278
|
+
# methods such as `add_observer`. Observers will be called with a new {BigSegmentStoreStatus}
|
279
|
+
# value whenever the status changes.
|
280
|
+
#
|
281
|
+
# @example Getting the current status
|
282
|
+
# status = client.big_segment_store_status_provider.status
|
283
|
+
#
|
284
|
+
# @example Subscribing to status notifications
|
285
|
+
# client.big_segment_store_status_provider.add_observer(self, :big_segments_status_changed)
|
286
|
+
#
|
287
|
+
# def big_segments_status_changed(new_status)
|
288
|
+
# puts "Big segment store status is now: #{new_status}"
|
289
|
+
# end
|
290
|
+
#
|
291
|
+
module BigSegmentStoreStatusProvider
|
292
|
+
include Observable
|
293
|
+
#
|
294
|
+
# Gets the current status of the store, if known.
|
295
|
+
#
|
296
|
+
# @return [BigSegmentStoreStatus] the status, or nil if the SDK has not yet queried the Big
|
297
|
+
# Segment store status
|
298
|
+
#
|
299
|
+
def status
|
300
|
+
end
|
301
|
+
end
|
152
302
|
end
|
153
303
|
end
|
data/lib/ldclient-rb/ldclient.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require "ldclient-rb/impl/big_segments"
|
1
2
|
require "ldclient-rb/impl/diagnostic_events"
|
2
3
|
require "ldclient-rb/impl/evaluator"
|
3
4
|
require "ldclient-rb/impl/event_factory"
|
@@ -57,10 +58,14 @@ module LaunchDarkly
|
|
57
58
|
updated_config.instance_variable_set(:@feature_store, @store)
|
58
59
|
@config = updated_config
|
59
60
|
|
61
|
+
@big_segment_store_manager = Impl::BigSegmentStoreManager.new(config.big_segments, @config.logger)
|
62
|
+
@big_segment_store_status_provider = @big_segment_store_manager.status_provider
|
63
|
+
|
60
64
|
get_flag = lambda { |key| @store.get(FEATURES, key) }
|
61
65
|
get_segment = lambda { |key| @store.get(SEGMENTS, key) }
|
62
|
-
|
63
|
-
|
66
|
+
get_big_segments_membership = lambda { |key| @big_segment_store_manager.get_user_membership(key) }
|
67
|
+
@evaluator = LaunchDarkly::Impl::Evaluator.new(get_flag, get_segment, get_big_segments_membership, @config.logger)
|
68
|
+
|
64
69
|
if !@config.offline? && @config.send_events && !@config.diagnostic_opt_out?
|
65
70
|
diagnostic_accumulator = Impl::DiagnosticAccumulator.new(Impl::DiagnosticAccumulator.create_diagnostic_id(sdk_key))
|
66
71
|
else
|
@@ -132,7 +137,7 @@ module LaunchDarkly
|
|
132
137
|
|
133
138
|
#
|
134
139
|
# Creates a hash string that can be used by the JavaScript SDK to identify a user.
|
135
|
-
# For more information, see [Secure mode](https://docs.launchdarkly.com/
|
140
|
+
# For more information, see [Secure mode](https://docs.launchdarkly.com/sdk/features/secure-mode#ruby).
|
136
141
|
#
|
137
142
|
# @param user [Hash] the user properties
|
138
143
|
# @return [String] a hash string
|
@@ -172,11 +177,11 @@ module LaunchDarkly
|
|
172
177
|
#
|
173
178
|
# Other supported user attributes include IP address, country code, and an arbitrary hash of
|
174
179
|
# custom attributes. For more about the supported user properties and how they work in
|
175
|
-
# LaunchDarkly, see [Targeting users](https://docs.launchdarkly.com/
|
180
|
+
# LaunchDarkly, see [Targeting users](https://docs.launchdarkly.com/home/flags/targeting-users).
|
176
181
|
#
|
177
182
|
# The optional `:privateAttributeNames` user property allows you to specify a list of
|
178
183
|
# attribute names that should not be sent back to LaunchDarkly.
|
179
|
-
# [Private attributes](https://docs.launchdarkly.com/
|
184
|
+
# [Private attributes](https://docs.launchdarkly.com/home/users/attributes#creating-private-user-attributes)
|
180
185
|
# can also be configured globally in {Config}.
|
181
186
|
#
|
182
187
|
# @example Basic user hash
|
@@ -213,7 +218,7 @@ module LaunchDarkly
|
|
213
218
|
# be included in analytics events, if you are capturing detailed event data for this flag.
|
214
219
|
#
|
215
220
|
# For more information, see the reference guide on
|
216
|
-
# [Evaluation reasons](https://docs.launchdarkly.com/
|
221
|
+
# [Evaluation reasons](https://docs.launchdarkly.com/sdk/concepts/evaluation-reasons).
|
217
222
|
#
|
218
223
|
# @param key [String] the unique feature key for the feature flag, as shown
|
219
224
|
# on the LaunchDarkly dashboard
|
@@ -260,7 +265,7 @@ module LaunchDarkly
|
|
260
265
|
#
|
261
266
|
# As of this version’s release date, the LaunchDarkly service does not support the `metricValue`
|
262
267
|
# parameter. As a result, specifying `metricValue` will not yet produce any different behavior
|
263
|
-
# from omitting it. Refer to the [SDK reference guide](https://docs.launchdarkly.com/
|
268
|
+
# from omitting it. Refer to the [SDK reference guide](https://docs.launchdarkly.com/sdk/features/events#ruby)
|
264
269
|
# for the latest status.
|
265
270
|
#
|
266
271
|
# @param event_name [String] The name of the event
|
@@ -375,9 +380,18 @@ module LaunchDarkly
|
|
375
380
|
@config.logger.info { "[LDClient] Closing LaunchDarkly client..." }
|
376
381
|
@data_source.stop
|
377
382
|
@event_processor.stop
|
383
|
+
@big_segment_store_manager.stop
|
378
384
|
@store.stop
|
379
385
|
end
|
380
386
|
|
387
|
+
#
|
388
|
+
# Returns an interface for tracking the status of a Big Segment store.
|
389
|
+
#
|
390
|
+
# The {BigSegmentStoreStatusProvider} has methods for checking whether the Big Segment store
|
391
|
+
# is (as far as the SDK knows) currently operational and tracking changes in this status.
|
392
|
+
#
|
393
|
+
attr_reader :big_segment_store_status_provider
|
394
|
+
|
381
395
|
private
|
382
396
|
|
383
397
|
def create_default_data_source(sdk_key, config, diagnostic_accumulator)
|
data/lib/ldclient-rb/polling.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "ldclient-rb/impl/repeating_task"
|
2
|
+
|
1
3
|
require "concurrent/atomics"
|
2
4
|
require "thread"
|
3
5
|
|
@@ -9,8 +11,8 @@ module LaunchDarkly
|
|
9
11
|
@requestor = requestor
|
10
12
|
@initialized = Concurrent::AtomicBoolean.new(false)
|
11
13
|
@started = Concurrent::AtomicBoolean.new(false)
|
12
|
-
@stopped = Concurrent::AtomicBoolean.new(false)
|
13
14
|
@ready = Concurrent::Event.new
|
15
|
+
@task = Impl::RepeatingTask.new(@config.poll_interval, 0, -> { self.poll }, @config.logger)
|
14
16
|
end
|
15
17
|
|
16
18
|
def initialized?
|
@@ -20,56 +22,35 @@ module LaunchDarkly
|
|
20
22
|
def start
|
21
23
|
return @ready unless @started.make_true
|
22
24
|
@config.logger.info { "[LDClient] Initializing polling connection" }
|
23
|
-
|
25
|
+
@task.start
|
24
26
|
@ready
|
25
27
|
end
|
26
28
|
|
27
29
|
def stop
|
28
|
-
|
29
|
-
|
30
|
-
@worker.run # causes the thread to wake up if it's currently in a sleep
|
31
|
-
@worker.join
|
32
|
-
end
|
33
|
-
@config.logger.info { "[LDClient] Polling connection stopped" }
|
34
|
-
end
|
30
|
+
@task.stop
|
31
|
+
@config.logger.info { "[LDClient] Polling connection stopped" }
|
35
32
|
end
|
36
33
|
|
37
34
|
def poll
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
@
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def create_worker
|
49
|
-
@worker = Thread.new do
|
50
|
-
@config.logger.debug { "[LDClient] Starting polling worker" }
|
51
|
-
while !@stopped.value do
|
52
|
-
started_at = Time.now
|
53
|
-
begin
|
54
|
-
poll
|
55
|
-
rescue UnexpectedResponseError => e
|
56
|
-
message = Util.http_error_message(e.status, "polling request", "will retry")
|
57
|
-
@config.logger.error { "[LDClient] #{message}" };
|
58
|
-
if !Util.http_error_recoverable?(e.status)
|
59
|
-
@ready.set # if client was waiting on us, make it stop waiting - has no effect if already set
|
60
|
-
stop
|
61
|
-
end
|
62
|
-
rescue StandardError => exn
|
63
|
-
Util.log_exception(@config.logger, "Exception while polling", exn)
|
64
|
-
end
|
65
|
-
delta = @config.poll_interval - (Time.now - started_at)
|
66
|
-
if delta > 0
|
67
|
-
sleep(delta)
|
35
|
+
begin
|
36
|
+
all_data = @requestor.request_all_data
|
37
|
+
if all_data
|
38
|
+
@config.feature_store.init(all_data)
|
39
|
+
if @initialized.make_true
|
40
|
+
@config.logger.info { "[LDClient] Polling connection initialized" }
|
41
|
+
@ready.set
|
68
42
|
end
|
69
43
|
end
|
44
|
+
rescue UnexpectedResponseError => e
|
45
|
+
message = Util.http_error_message(e.status, "polling request", "will retry")
|
46
|
+
@config.logger.error { "[LDClient] #{message}" };
|
47
|
+
if !Util.http_error_recoverable?(e.status)
|
48
|
+
@ready.set # if client was waiting on us, make it stop waiting - has no effect if already set
|
49
|
+
stop
|
50
|
+
end
|
51
|
+
rescue StandardError => e
|
52
|
+
Util.log_exception(@config.logger, "Exception while polling", e)
|
70
53
|
end
|
71
54
|
end
|
72
|
-
|
73
|
-
private :poll, :create_worker
|
74
55
|
end
|
75
56
|
end
|
data/lib/ldclient-rb/util.rb
CHANGED
data/lib/ldclient-rb/version.rb
CHANGED