ldclient-rb 5.4.3 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.circleci/config.yml +33 -6
- data/CHANGELOG.md +19 -0
- data/CONTRIBUTING.md +0 -12
- data/Gemfile.lock +22 -3
- data/README.md +41 -35
- data/ldclient-rb.gemspec +4 -3
- data/lib/ldclient-rb.rb +9 -1
- data/lib/ldclient-rb/cache_store.rb +1 -0
- data/lib/ldclient-rb/config.rb +201 -90
- data/lib/ldclient-rb/evaluation.rb +56 -8
- data/lib/ldclient-rb/event_summarizer.rb +3 -0
- data/lib/ldclient-rb/events.rb +16 -0
- data/lib/ldclient-rb/expiring_cache.rb +1 -0
- data/lib/ldclient-rb/file_data_source.rb +18 -13
- data/lib/ldclient-rb/flags_state.rb +3 -2
- data/lib/ldclient-rb/impl.rb +13 -0
- data/lib/ldclient-rb/impl/integrations/consul_impl.rb +158 -0
- data/lib/ldclient-rb/impl/integrations/dynamodb_impl.rb +228 -0
- data/lib/ldclient-rb/impl/integrations/redis_impl.rb +155 -0
- data/lib/ldclient-rb/impl/store_client_wrapper.rb +47 -0
- data/lib/ldclient-rb/impl/store_data_set_sorter.rb +55 -0
- data/lib/ldclient-rb/in_memory_store.rb +15 -4
- data/lib/ldclient-rb/integrations.rb +55 -0
- data/lib/ldclient-rb/integrations/consul.rb +38 -0
- data/lib/ldclient-rb/integrations/dynamodb.rb +47 -0
- data/lib/ldclient-rb/integrations/redis.rb +55 -0
- data/lib/ldclient-rb/integrations/util/store_wrapper.rb +230 -0
- data/lib/ldclient-rb/interfaces.rb +153 -0
- data/lib/ldclient-rb/ldclient.rb +135 -77
- data/lib/ldclient-rb/memoized_value.rb +2 -0
- data/lib/ldclient-rb/newrelic.rb +1 -0
- data/lib/ldclient-rb/non_blocking_thread_pool.rb +3 -3
- data/lib/ldclient-rb/polling.rb +1 -0
- data/lib/ldclient-rb/redis_store.rb +24 -190
- data/lib/ldclient-rb/requestor.rb +3 -2
- data/lib/ldclient-rb/simple_lru_cache.rb +1 -0
- data/lib/ldclient-rb/stream.rb +22 -10
- data/lib/ldclient-rb/user_filter.rb +1 -0
- data/lib/ldclient-rb/util.rb +1 -0
- data/lib/ldclient-rb/version.rb +1 -1
- data/scripts/gendocs.sh +12 -0
- data/spec/feature_store_spec_base.rb +173 -72
- data/spec/file_data_source_spec.rb +2 -2
- data/spec/http_util.rb +103 -0
- data/spec/in_memory_feature_store_spec.rb +1 -1
- data/spec/integrations/consul_feature_store_spec.rb +41 -0
- data/spec/integrations/dynamodb_feature_store_spec.rb +104 -0
- data/spec/integrations/store_wrapper_spec.rb +276 -0
- data/spec/ldclient_spec.rb +83 -4
- data/spec/redis_feature_store_spec.rb +25 -16
- data/spec/requestor_spec.rb +44 -38
- data/spec/stream_spec.rb +18 -18
- metadata +55 -33
- data/lib/sse_client.rb +0 -4
- data/lib/sse_client/backoff.rb +0 -38
- data/lib/sse_client/sse_client.rb +0 -171
- data/lib/sse_client/sse_events.rb +0 -67
- data/lib/sse_client/streaming_http.rb +0 -199
- data/spec/sse_client/sse_client_spec.rb +0 -177
- data/spec/sse_client/sse_events_spec.rb +0 -100
- data/spec/sse_client/sse_shared.rb +0 -82
- data/spec/sse_client/streaming_http_spec.rb +0 -263
data/spec/ldclient_spec.rb
CHANGED
@@ -7,8 +7,8 @@ describe LaunchDarkly::LDClient do
|
|
7
7
|
let(:offline_client) do
|
8
8
|
subject.new("secret", offline_config)
|
9
9
|
end
|
10
|
-
let(:
|
11
|
-
let(:config) { LaunchDarkly::Config.new({send_events: false,
|
10
|
+
let(:null_data) { LaunchDarkly::NullUpdateProcessor.new }
|
11
|
+
let(:config) { LaunchDarkly::Config.new({send_events: false, data_source: null_data}) }
|
12
12
|
let(:client) do
|
13
13
|
subject.new("secret", config)
|
14
14
|
end
|
@@ -357,7 +357,7 @@ describe LaunchDarkly::LDClient do
|
|
357
357
|
end
|
358
358
|
|
359
359
|
describe 'with send_events: false' do
|
360
|
-
let(:config) { LaunchDarkly::Config.new({offline: true, send_events: false,
|
360
|
+
let(:config) { LaunchDarkly::Config.new({offline: true, send_events: false, data_source: null_data}) }
|
361
361
|
let(:client) { subject.new("secret", config) }
|
362
362
|
|
363
363
|
it "uses a NullEventProcessor" do
|
@@ -367,7 +367,7 @@ describe LaunchDarkly::LDClient do
|
|
367
367
|
end
|
368
368
|
|
369
369
|
describe 'with send_events: true' do
|
370
|
-
let(:config_with_events) { LaunchDarkly::Config.new({offline: false, send_events: true,
|
370
|
+
let(:config_with_events) { LaunchDarkly::Config.new({offline: false, send_events: true, data_source: null_data}) }
|
371
371
|
let(:client_with_events) { subject.new("secret", config_with_events) }
|
372
372
|
|
373
373
|
it "does not use a NullEventProcessor" do
|
@@ -375,4 +375,83 @@ describe LaunchDarkly::LDClient do
|
|
375
375
|
expect(ep).not_to be_a(LaunchDarkly::NullEventProcessor)
|
376
376
|
end
|
377
377
|
end
|
378
|
+
|
379
|
+
describe "feature store data ordering" do
|
380
|
+
let(:dependency_ordering_test_data) {
|
381
|
+
{
|
382
|
+
LaunchDarkly::FEATURES => {
|
383
|
+
a: { key: "a", prerequisites: [ { key: "b" }, { key: "c" } ] },
|
384
|
+
b: { key: "b", prerequisites: [ { key: "c" }, { key: "e" } ] },
|
385
|
+
c: { key: "c" },
|
386
|
+
d: { key: "d" },
|
387
|
+
e: { key: "e" },
|
388
|
+
f: { key: "f" }
|
389
|
+
},
|
390
|
+
LaunchDarkly::SEGMENTS => {
|
391
|
+
o: { key: "o" }
|
392
|
+
}
|
393
|
+
}
|
394
|
+
}
|
395
|
+
|
396
|
+
class FakeFeatureStore
|
397
|
+
attr_reader :received_data
|
398
|
+
|
399
|
+
def init(all_data)
|
400
|
+
@received_data = all_data
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
class FakeUpdateProcessor
|
405
|
+
def initialize(store, data)
|
406
|
+
@store = store
|
407
|
+
@data = data
|
408
|
+
end
|
409
|
+
|
410
|
+
def start
|
411
|
+
@store.init(@data)
|
412
|
+
ev = Concurrent::Event.new
|
413
|
+
ev.set
|
414
|
+
ev
|
415
|
+
end
|
416
|
+
|
417
|
+
def stop
|
418
|
+
end
|
419
|
+
|
420
|
+
def initialized?
|
421
|
+
true
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
it "passes data set to feature store in correct order on init" do
|
426
|
+
store = FakeFeatureStore.new
|
427
|
+
data_source_factory = lambda { |sdk_key, config| FakeUpdateProcessor.new(config.feature_store,
|
428
|
+
dependency_ordering_test_data) }
|
429
|
+
config = LaunchDarkly::Config.new(send_events: false, feature_store: store, data_source: data_source_factory)
|
430
|
+
client = subject.new("secret", config)
|
431
|
+
|
432
|
+
data = store.received_data
|
433
|
+
expect(data).not_to be_nil
|
434
|
+
expect(data.count).to eq(2)
|
435
|
+
|
436
|
+
# Segments should always come first
|
437
|
+
expect(data.keys[0]).to be(LaunchDarkly::SEGMENTS)
|
438
|
+
expect(data.values[0].count).to eq(dependency_ordering_test_data[LaunchDarkly::SEGMENTS].count)
|
439
|
+
|
440
|
+
# Features should be ordered so that a flag always appears after its prerequisites, if any
|
441
|
+
expect(data.keys[1]).to be(LaunchDarkly::FEATURES)
|
442
|
+
flags_map = data.values[1]
|
443
|
+
flags_list = flags_map.values
|
444
|
+
expect(flags_list.count).to eq(dependency_ordering_test_data[LaunchDarkly::FEATURES].count)
|
445
|
+
flags_list.each_with_index do |item, item_index|
|
446
|
+
(item[:prerequisites] || []).each do |prereq|
|
447
|
+
prereq = flags_map[prereq[:key].to_sym]
|
448
|
+
prereq_index = flags_list.index(prereq)
|
449
|
+
if prereq_index > item_index
|
450
|
+
all_keys = (flags_list.map { |f| f[:key] }).join(", ")
|
451
|
+
raise "#{item[:key]} depends on #{prereq[:key]}, but #{item[:key]} was listed first; keys in order are [#{all_keys}]"
|
452
|
+
end
|
453
|
+
end
|
454
|
+
end
|
455
|
+
end
|
456
|
+
end
|
378
457
|
end
|
@@ -9,13 +9,22 @@ $my_prefix = 'testprefix'
|
|
9
9
|
$null_log = ::Logger.new($stdout)
|
10
10
|
$null_log.level = ::Logger::FATAL
|
11
11
|
|
12
|
+
$base_opts = {
|
13
|
+
prefix: $my_prefix,
|
14
|
+
logger: $null_log
|
15
|
+
}
|
12
16
|
|
13
|
-
def create_redis_store()
|
14
|
-
LaunchDarkly::RedisFeatureStore.new(
|
17
|
+
def create_redis_store(opts = {})
|
18
|
+
LaunchDarkly::RedisFeatureStore.new($base_opts.merge(opts).merge({ expiration: 60 }))
|
15
19
|
end
|
16
20
|
|
17
|
-
def create_redis_store_uncached()
|
18
|
-
LaunchDarkly::RedisFeatureStore.new(
|
21
|
+
def create_redis_store_uncached(opts = {})
|
22
|
+
LaunchDarkly::RedisFeatureStore.new($base_opts.merge(opts).merge({ expiration: 0 }))
|
23
|
+
end
|
24
|
+
|
25
|
+
def clear_all_data
|
26
|
+
client = Redis.new
|
27
|
+
client.flushdb
|
19
28
|
end
|
20
29
|
|
21
30
|
|
@@ -25,16 +34,17 @@ describe LaunchDarkly::RedisFeatureStore do
|
|
25
34
|
# These tests will all fail if there isn't a Redis instance running on the default port.
|
26
35
|
|
27
36
|
context "real Redis with local cache" do
|
28
|
-
include_examples "feature_store", method(:create_redis_store)
|
37
|
+
include_examples "feature_store", method(:create_redis_store), method(:clear_all_data)
|
29
38
|
end
|
30
39
|
|
31
40
|
context "real Redis without local cache" do
|
32
|
-
include_examples "feature_store", method(:create_redis_store_uncached)
|
41
|
+
include_examples "feature_store", method(:create_redis_store_uncached), method(:clear_all_data)
|
33
42
|
end
|
34
43
|
|
35
|
-
def
|
44
|
+
def make_concurrent_modifier_test_hook(other_client, flag, start_version, end_version)
|
45
|
+
test_hook = Object.new
|
36
46
|
version_counter = start_version
|
37
|
-
expect(
|
47
|
+
expect(test_hook).to receive(:before_update_transaction) { |base_key, key|
|
38
48
|
if version_counter <= end_version
|
39
49
|
new_flag = flag.clone
|
40
50
|
new_flag[:version] = version_counter
|
@@ -42,18 +52,18 @@ describe LaunchDarkly::RedisFeatureStore do
|
|
42
52
|
version_counter = version_counter + 1
|
43
53
|
end
|
44
54
|
}.at_least(:once)
|
55
|
+
test_hook
|
45
56
|
end
|
46
57
|
|
47
58
|
it "handles upsert race condition against external client with lower version" do
|
48
|
-
store = create_redis_store
|
49
59
|
other_client = Redis.new({ url: "redis://localhost:6379" })
|
60
|
+
flag = { key: "foo", version: 1 }
|
61
|
+
test_hook = make_concurrent_modifier_test_hook(other_client, flag, 2, 4)
|
62
|
+
store = create_redis_store({ test_hook: test_hook })
|
50
63
|
|
51
64
|
begin
|
52
|
-
flag = { key: "foo", version: 1 }
|
53
65
|
store.init(LaunchDarkly::FEATURES => { flag[:key] => flag })
|
54
66
|
|
55
|
-
add_concurrent_modifier(store, other_client, flag, 2, 4)
|
56
|
-
|
57
67
|
my_ver = { key: "foo", version: 10 }
|
58
68
|
store.upsert(LaunchDarkly::FEATURES, my_ver)
|
59
69
|
result = store.get(LaunchDarkly::FEATURES, flag[:key])
|
@@ -64,15 +74,14 @@ describe LaunchDarkly::RedisFeatureStore do
|
|
64
74
|
end
|
65
75
|
|
66
76
|
it "handles upsert race condition against external client with higher version" do
|
67
|
-
store = create_redis_store
|
68
77
|
other_client = Redis.new({ url: "redis://localhost:6379" })
|
78
|
+
flag = { key: "foo", version: 1 }
|
79
|
+
test_hook = make_concurrent_modifier_test_hook(other_client, flag, 3, 3)
|
80
|
+
store = create_redis_store({ test_hook: test_hook })
|
69
81
|
|
70
82
|
begin
|
71
|
-
flag = { key: "foo", version: 1 }
|
72
83
|
store.init(LaunchDarkly::FEATURES => { flag[:key] => flag })
|
73
84
|
|
74
|
-
add_concurrent_modifier(store, other_client, flag, 3, 3)
|
75
|
-
|
76
85
|
my_ver = { key: "foo", version: 2 }
|
77
86
|
store.upsert(LaunchDarkly::FEATURES, my_ver)
|
78
87
|
result = store.get(LaunchDarkly::FEATURES, flag[:key])
|
data/spec/requestor_spec.rb
CHANGED
@@ -1,52 +1,58 @@
|
|
1
|
+
require "http_util"
|
1
2
|
require "spec_helper"
|
2
|
-
require "faraday"
|
3
3
|
|
4
4
|
describe LaunchDarkly::Requestor do
|
5
5
|
describe ".request_all_flags" do
|
6
6
|
describe "with a proxy" do
|
7
|
-
let(:requestor) {
|
8
|
-
LaunchDarkly::Requestor.new(
|
9
|
-
"key",
|
10
|
-
LaunchDarkly::Config.new({
|
11
|
-
:proxy => "http://proxy.com",
|
12
|
-
:base_uri => "http://ld.com"
|
13
|
-
})
|
14
|
-
)
|
15
|
-
}
|
16
7
|
it "converts the proxy option" do
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
8
|
+
content = '{"flags": {"flagkey": {"key": "flagkey"}}}'
|
9
|
+
with_server do |server|
|
10
|
+
server.setup_ok_response("/sdk/latest-all", content, "application/json", { "etag" => "x" })
|
11
|
+
with_server(StubProxyServer.new) do |proxy|
|
12
|
+
config = LaunchDarkly::Config.new(base_uri: server.base_uri.to_s, proxy: proxy.base_uri.to_s)
|
13
|
+
r = LaunchDarkly::Requestor.new("sdk-key", config)
|
14
|
+
result = r.request_all_data
|
15
|
+
expect(result).to eq(JSON.parse(content, symbolize_names: true))
|
16
|
+
end
|
25
17
|
end
|
26
|
-
|
27
|
-
requestor.request_all_data()
|
28
18
|
end
|
29
19
|
end
|
30
20
|
describe "without a proxy" do
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
})
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
21
|
+
it "sends headers" do
|
22
|
+
content = '{"flags": {}}'
|
23
|
+
sdk_key = 'sdk-key'
|
24
|
+
with_server do |server|
|
25
|
+
server.setup_ok_response("/sdk/latest-all", content, "application/json", { "etag" => "x" })
|
26
|
+
r = LaunchDarkly::Requestor.new(sdk_key, LaunchDarkly::Config.new({ base_uri: server.base_uri.to_s }))
|
27
|
+
r.request_all_data
|
28
|
+
expect(server.requests.length).to eq 1
|
29
|
+
req = server.requests[0]
|
30
|
+
expect(req.header['authorization']).to eq [sdk_key]
|
31
|
+
expect(req.header['user-agent']).to eq ["RubyClient/" + LaunchDarkly::VERSION]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "receives data" do
|
36
|
+
content = '{"flags": {"flagkey": {"key": "flagkey"}}}'
|
37
|
+
with_server do |server|
|
38
|
+
server.setup_ok_response("/sdk/latest-all", content, "application/json", { "etag" => "x" })
|
39
|
+
r = LaunchDarkly::Requestor.new("sdk-key", LaunchDarkly::Config.new({ base_uri: server.base_uri.to_s }))
|
40
|
+
result = r.request_all_data
|
41
|
+
expect(result).to eq(JSON.parse(content, symbolize_names: true))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "handles Unicode content" do
|
46
|
+
content = '{"flags": {"flagkey": {"key": "flagkey", "variations": ["blue", "grėeń"]}}}'
|
47
|
+
with_server do |server|
|
48
|
+
server.setup_ok_response("/sdk/latest-all", content, "application/json", { "etag" => "x" })
|
49
|
+
# Note that the ETag header here is important because without it, the HTTP cache will not be used,
|
50
|
+
# and the cache is what required a fix to handle Unicode properly. See:
|
51
|
+
# https://github.com/launchdarkly/ruby-client/issues/90
|
52
|
+
r = LaunchDarkly::Requestor.new("sdk-key", LaunchDarkly::Config.new({ base_uri: server.base_uri.to_s }))
|
53
|
+
result = r.request_all_data
|
54
|
+
expect(result).to eq(JSON.parse(content, symbolize_names: true))
|
48
55
|
end
|
49
|
-
requestor.request_all_data()
|
50
56
|
end
|
51
57
|
end
|
52
58
|
end
|
data/spec/stream_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
+
require "ld-eventsource"
|
1
2
|
require "spec_helper"
|
2
|
-
require 'ostruct'
|
3
3
|
|
4
4
|
describe LaunchDarkly::StreamProcessor do
|
5
5
|
subject { LaunchDarkly::StreamProcessor }
|
@@ -8,52 +8,52 @@ describe LaunchDarkly::StreamProcessor do
|
|
8
8
|
let(:processor) { subject.new("sdk_key", config, requestor) }
|
9
9
|
|
10
10
|
describe '#process_message' do
|
11
|
-
let(:put_message) {
|
12
|
-
let(:patch_flag_message) {
|
13
|
-
let(:patch_seg_message) {
|
14
|
-
let(:delete_flag_message) {
|
15
|
-
let(:delete_seg_message) {
|
16
|
-
let(:indirect_patch_flag_message) {
|
17
|
-
let(:indirect_patch_segment_message) {
|
11
|
+
let(:put_message) { SSE::StreamEvent.new(:put, '{"data":{"flags":{"asdf": {"key": "asdf"}},"segments":{"segkey": {"key": "segkey"}}}}') }
|
12
|
+
let(:patch_flag_message) { SSE::StreamEvent.new(:patch, '{"path": "/flags/key", "data": {"key": "asdf", "version": 1}}') }
|
13
|
+
let(:patch_seg_message) { SSE::StreamEvent.new(:patch, '{"path": "/segments/key", "data": {"key": "asdf", "version": 1}}') }
|
14
|
+
let(:delete_flag_message) { SSE::StreamEvent.new(:delete, '{"path": "/flags/key", "version": 2}') }
|
15
|
+
let(:delete_seg_message) { SSE::StreamEvent.new(:delete, '{"path": "/segments/key", "version": 2}') }
|
16
|
+
let(:indirect_patch_flag_message) { SSE::StreamEvent.new(:'indirect/patch', "/flags/key") }
|
17
|
+
let(:indirect_patch_segment_message) { SSE::StreamEvent.new(:'indirect/patch', "/segments/key") }
|
18
18
|
|
19
19
|
it "will accept PUT methods" do
|
20
|
-
processor.send(:process_message, put_message
|
20
|
+
processor.send(:process_message, put_message)
|
21
21
|
expect(config.feature_store.get(LaunchDarkly::FEATURES, "asdf")).to eq(key: "asdf")
|
22
22
|
expect(config.feature_store.get(LaunchDarkly::SEGMENTS, "segkey")).to eq(key: "segkey")
|
23
23
|
end
|
24
24
|
it "will accept PATCH methods for flags" do
|
25
|
-
processor.send(:process_message, patch_flag_message
|
25
|
+
processor.send(:process_message, patch_flag_message)
|
26
26
|
expect(config.feature_store.get(LaunchDarkly::FEATURES, "asdf")).to eq(key: "asdf", version: 1)
|
27
27
|
end
|
28
28
|
it "will accept PATCH methods for segments" do
|
29
|
-
processor.send(:process_message, patch_seg_message
|
29
|
+
processor.send(:process_message, patch_seg_message)
|
30
30
|
expect(config.feature_store.get(LaunchDarkly::SEGMENTS, "asdf")).to eq(key: "asdf", version: 1)
|
31
31
|
end
|
32
32
|
it "will accept DELETE methods for flags" do
|
33
|
-
processor.send(:process_message, patch_flag_message
|
34
|
-
processor.send(:process_message, delete_flag_message
|
33
|
+
processor.send(:process_message, patch_flag_message)
|
34
|
+
processor.send(:process_message, delete_flag_message)
|
35
35
|
expect(config.feature_store.get(LaunchDarkly::FEATURES, "key")).to eq(nil)
|
36
36
|
end
|
37
37
|
it "will accept DELETE methods for segments" do
|
38
|
-
processor.send(:process_message, patch_seg_message
|
39
|
-
processor.send(:process_message, delete_seg_message
|
38
|
+
processor.send(:process_message, patch_seg_message)
|
39
|
+
processor.send(:process_message, delete_seg_message)
|
40
40
|
expect(config.feature_store.get(LaunchDarkly::SEGMENTS, "key")).to eq(nil)
|
41
41
|
end
|
42
42
|
it "will accept INDIRECT PATCH method for flags" do
|
43
43
|
flag = { key: 'key', version: 1 }
|
44
44
|
allow(requestor).to receive(:request_flag).with(flag[:key]).and_return(flag)
|
45
|
-
processor.send(:process_message, indirect_patch_flag_message
|
45
|
+
processor.send(:process_message, indirect_patch_flag_message);
|
46
46
|
expect(config.feature_store.get(LaunchDarkly::FEATURES, flag[:key])).to eq(flag)
|
47
47
|
end
|
48
48
|
it "will accept INDIRECT PATCH method for segments" do
|
49
49
|
segment = { key: 'key', version: 1 }
|
50
50
|
allow(requestor).to receive(:request_segment).with(segment[:key]).and_return(segment)
|
51
|
-
processor.send(:process_message, indirect_patch_segment_message
|
51
|
+
processor.send(:process_message, indirect_patch_segment_message);
|
52
52
|
expect(config.feature_store.get(LaunchDarkly::SEGMENTS, segment[:key])).to eq(segment)
|
53
53
|
end
|
54
54
|
it "will log a warning if the method is not recognized" do
|
55
55
|
expect(processor.instance_variable_get(:@config).logger).to receive :warn
|
56
|
-
processor.send(:process_message,
|
56
|
+
processor.send(:process_message, SSE::StreamEvent.new(type: :get, data: "", id: nil))
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ldclient-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- LaunchDarkly
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-01-
|
11
|
+
date: 2019-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk-dynamodb
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.18'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.18'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +66,20 @@ dependencies:
|
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: diplomat
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 2.0.2
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 2.0.2
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: redis
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -245,33 +273,19 @@ dependencies:
|
|
245
273
|
- !ruby/object:Gem::Version
|
246
274
|
version: '1.0'
|
247
275
|
- !ruby/object:Gem::Dependency
|
248
|
-
name:
|
276
|
+
name: ld-eventsource
|
249
277
|
requirement: !ruby/object:Gem::Requirement
|
250
278
|
requirements:
|
251
279
|
- - "~>"
|
252
280
|
- !ruby/object:Gem::Version
|
253
|
-
version: 0
|
254
|
-
type: :runtime
|
255
|
-
prerelease: false
|
256
|
-
version_requirements: !ruby/object:Gem::Requirement
|
257
|
-
requirements:
|
258
|
-
- - "~>"
|
259
|
-
- !ruby/object:Gem::Version
|
260
|
-
version: 0.4.5
|
261
|
-
- !ruby/object:Gem::Dependency
|
262
|
-
name: socketry
|
263
|
-
requirement: !ruby/object:Gem::Requirement
|
264
|
-
requirements:
|
265
|
-
- - "~>"
|
266
|
-
- !ruby/object:Gem::Version
|
267
|
-
version: 0.5.1
|
281
|
+
version: '1.0'
|
268
282
|
type: :runtime
|
269
283
|
prerelease: false
|
270
284
|
version_requirements: !ruby/object:Gem::Requirement
|
271
285
|
requirements:
|
272
286
|
- - "~>"
|
273
287
|
- !ruby/object:Gem::Version
|
274
|
-
version: 0
|
288
|
+
version: '1.0'
|
275
289
|
description: Official LaunchDarkly SDK for Ruby
|
276
290
|
email:
|
277
291
|
- team@launchdarkly.com
|
@@ -305,7 +319,19 @@ files:
|
|
305
319
|
- lib/ldclient-rb/expiring_cache.rb
|
306
320
|
- lib/ldclient-rb/file_data_source.rb
|
307
321
|
- lib/ldclient-rb/flags_state.rb
|
322
|
+
- lib/ldclient-rb/impl.rb
|
323
|
+
- lib/ldclient-rb/impl/integrations/consul_impl.rb
|
324
|
+
- lib/ldclient-rb/impl/integrations/dynamodb_impl.rb
|
325
|
+
- lib/ldclient-rb/impl/integrations/redis_impl.rb
|
326
|
+
- lib/ldclient-rb/impl/store_client_wrapper.rb
|
327
|
+
- lib/ldclient-rb/impl/store_data_set_sorter.rb
|
308
328
|
- lib/ldclient-rb/in_memory_store.rb
|
329
|
+
- lib/ldclient-rb/integrations.rb
|
330
|
+
- lib/ldclient-rb/integrations/consul.rb
|
331
|
+
- lib/ldclient-rb/integrations/dynamodb.rb
|
332
|
+
- lib/ldclient-rb/integrations/redis.rb
|
333
|
+
- lib/ldclient-rb/integrations/util/store_wrapper.rb
|
334
|
+
- lib/ldclient-rb/interfaces.rb
|
309
335
|
- lib/ldclient-rb/ldclient.rb
|
310
336
|
- lib/ldclient-rb/memoized_value.rb
|
311
337
|
- lib/ldclient-rb/newrelic.rb
|
@@ -318,11 +344,7 @@ files:
|
|
318
344
|
- lib/ldclient-rb/user_filter.rb
|
319
345
|
- lib/ldclient-rb/util.rb
|
320
346
|
- lib/ldclient-rb/version.rb
|
321
|
-
-
|
322
|
-
- lib/sse_client/backoff.rb
|
323
|
-
- lib/sse_client/sse_client.rb
|
324
|
-
- lib/sse_client/sse_events.rb
|
325
|
-
- lib/sse_client/streaming_http.rb
|
347
|
+
- scripts/gendocs.sh
|
326
348
|
- scripts/release.sh
|
327
349
|
- spec/config_spec.rb
|
328
350
|
- spec/evaluation_spec.rb
|
@@ -337,7 +359,11 @@ files:
|
|
337
359
|
- spec/fixtures/sanitized_numeric_key_user.json
|
338
360
|
- spec/fixtures/user.json
|
339
361
|
- spec/flags_state_spec.rb
|
362
|
+
- spec/http_util.rb
|
340
363
|
- spec/in_memory_feature_store_spec.rb
|
364
|
+
- spec/integrations/consul_feature_store_spec.rb
|
365
|
+
- spec/integrations/dynamodb_feature_store_spec.rb
|
366
|
+
- spec/integrations/store_wrapper_spec.rb
|
341
367
|
- spec/ldclient_spec.rb
|
342
368
|
- spec/newrelic_spec.rb
|
343
369
|
- spec/polling_spec.rb
|
@@ -346,10 +372,6 @@ files:
|
|
346
372
|
- spec/segment_store_spec_base.rb
|
347
373
|
- spec/simple_lru_cache_spec.rb
|
348
374
|
- spec/spec_helper.rb
|
349
|
-
- spec/sse_client/sse_client_spec.rb
|
350
|
-
- spec/sse_client/sse_events_spec.rb
|
351
|
-
- spec/sse_client/sse_shared.rb
|
352
|
-
- spec/sse_client/streaming_http_spec.rb
|
353
375
|
- spec/store_spec.rb
|
354
376
|
- spec/stream_spec.rb
|
355
377
|
- spec/user_filter_spec.rb
|
@@ -357,7 +379,7 @@ files:
|
|
357
379
|
- spec/version_spec.rb
|
358
380
|
homepage: https://github.com/launchdarkly/ruby-client
|
359
381
|
licenses:
|
360
|
-
- Apache
|
382
|
+
- Apache-2.0
|
361
383
|
metadata: {}
|
362
384
|
post_install_message:
|
363
385
|
rdoc_options: []
|
@@ -393,7 +415,11 @@ test_files:
|
|
393
415
|
- spec/fixtures/sanitized_numeric_key_user.json
|
394
416
|
- spec/fixtures/user.json
|
395
417
|
- spec/flags_state_spec.rb
|
418
|
+
- spec/http_util.rb
|
396
419
|
- spec/in_memory_feature_store_spec.rb
|
420
|
+
- spec/integrations/consul_feature_store_spec.rb
|
421
|
+
- spec/integrations/dynamodb_feature_store_spec.rb
|
422
|
+
- spec/integrations/store_wrapper_spec.rb
|
397
423
|
- spec/ldclient_spec.rb
|
398
424
|
- spec/newrelic_spec.rb
|
399
425
|
- spec/polling_spec.rb
|
@@ -402,10 +428,6 @@ test_files:
|
|
402
428
|
- spec/segment_store_spec_base.rb
|
403
429
|
- spec/simple_lru_cache_spec.rb
|
404
430
|
- spec/spec_helper.rb
|
405
|
-
- spec/sse_client/sse_client_spec.rb
|
406
|
-
- spec/sse_client/sse_events_spec.rb
|
407
|
-
- spec/sse_client/sse_shared.rb
|
408
|
-
- spec/sse_client/streaming_http_spec.rb
|
409
431
|
- spec/store_spec.rb
|
410
432
|
- spec/stream_spec.rb
|
411
433
|
- spec/user_filter_spec.rb
|