Skip to content

Commit 71320e2

Browse files
authored
Merge pull request #529 from splitio/post-data-destroy
fixed posting data before shutdown
2 parents cecc9f3 + 4c9e171 commit 71320e2

File tree

4 files changed

+104
-31
lines changed

4 files changed

+104
-31
lines changed

lib/splitclient-rb/cache/repositories/events/memory_repository.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ def clear
2929
@adapter.clear
3030
end
3131

32+
def empty?
33+
@adapter.empty?
34+
end
35+
3236
def batch
3337
return [] if @config.events_queue_size.zero?
3438

lib/splitclient-rb/cache/repositories/events_repository.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ def post_events
2525
@config.log_found_exception(__method__.to_s, e)
2626
end
2727

28+
def empty?
29+
@repository.empty?
30+
end
31+
2832
protected
2933

3034
def metadata

lib/splitclient-rb/clients/split_client.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,16 @@ def get_treatments_with_config_by_flag_sets(key, flag_sets, attributes = {})
9696

9797
def destroy
9898
@config.logger.info('Split client shutdown started...') if @config.debug_enabled
99-
99+
if !@config.cache_adapter.is_a?(SplitIoClient::Cache::Adapters::RedisAdapter) && @config.impressions_mode != :none &&
100+
(!@impressions_repository.empty? || !@events_repository.empty?)
101+
@config.logger.debug("Impressions and/or Events cache is not empty")
102+
# Adding small delay to ensure sender threads are fully running
103+
sleep(0.1)
104+
if !@config.threads.key?(:impressions_sender) || !@config.threads.key?(:events_sender)
105+
@config.logger.debug("Periodic data recording thread has not started yet, waiting for service startup.")
106+
@config.threads[:start_sdk].join(5) if @config.threads.key?(:start_sdk)
107+
end
108+
end
100109
@config.threads.select { |name, thread| name.to_s.end_with? 'sender' }.values.each do |thread|
101110
thread.raise(SplitIoClient::SDKShutdownException)
102111
thread.join

spec/splitclient/split_client_spec.rb

Lines changed: 86 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,96 @@
33
require 'spec_helper'
44

55
describe SplitIoClient::SplitClient do
6-
let(:config) { SplitIoClient::SplitConfig.new(cache_adapter: :memory, impressions_mode: :debug) }
7-
let(:segments_repository) { SplitIoClient::Cache::Repositories::SegmentsRepository.new(config) }
8-
let(:flag_sets_repository) {SplitIoClient::Cache::Repositories::MemoryFlagSetsRepository.new([]) }
9-
let(:flag_set_filter) {SplitIoClient::Cache::Filter::FlagSetsFilter.new([]) }
10-
let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) }
11-
let(:impressions_repository) {SplitIoClient::Cache::Repositories::ImpressionsRepository.new(config) }
12-
let(:runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) }
13-
let(:events_repository) { SplitIoClient::Cache::Repositories::EventsRepository.new(config, 'sdk_key', runtime_producer) }
14-
let(:impression_manager) { SplitIoClient::Engine::Common::ImpressionManager.new(config, impressions_repository, SplitIoClient::Engine::Common::NoopImpressionCounter.new, runtime_producer, SplitIoClient::Observers::NoopImpressionObserver.new, SplitIoClient::Engine::Impressions::NoopUniqueKeysTracker.new) }
15-
let(:evaluation_producer) { SplitIoClient::Telemetry::EvaluationProducer.new(config) }
16-
let(:evaluator) { SplitIoClient::Engine::Parser::Evaluator.new(segments_repository, splits_repository, config) }
17-
let(:split_client) { SplitIoClient::SplitClient.new('sdk_key', {:splits => splits_repository, :segments => segments_repository, :impressions => impressions_repository, :events => events_repository}, nil, config, impression_manager, evaluation_producer, evaluator, SplitIoClient::Validators.new(config)) }
18-
19-
let(:splits) do
20-
File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/splits.json'))
21-
end
6+
context 'split client methods' do
7+
let(:config) { SplitIoClient::SplitConfig.new(cache_adapter: :memory, impressions_mode: :debug) }
8+
let(:segments_repository) { SplitIoClient::Cache::Repositories::SegmentsRepository.new(config) }
9+
let(:flag_sets_repository) {SplitIoClient::Cache::Repositories::MemoryFlagSetsRepository.new([]) }
10+
let(:flag_set_filter) {SplitIoClient::Cache::Filter::FlagSetsFilter.new([]) }
11+
let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) }
12+
let(:impressions_repository) {SplitIoClient::Cache::Repositories::ImpressionsRepository.new(config) }
13+
let(:runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) }
14+
let(:events_repository) { SplitIoClient::Cache::Repositories::EventsRepository.new(config, 'sdk_key', runtime_producer) }
15+
let(:impression_manager) { SplitIoClient::Engine::Common::ImpressionManager.new(config, impressions_repository, SplitIoClient::Engine::Common::NoopImpressionCounter.new, runtime_producer, SplitIoClient::Observers::NoopImpressionObserver.new, SplitIoClient::Engine::Impressions::NoopUniqueKeysTracker.new) }
16+
let(:evaluation_producer) { SplitIoClient::Telemetry::EvaluationProducer.new(config) }
17+
let(:evaluator) { SplitIoClient::Engine::Parser::Evaluator.new(segments_repository, splits_repository, config) }
18+
let(:split_client) { SplitIoClient::SplitClient.new('sdk_key', {:splits => splits_repository, :segments => segments_repository, :impressions => impressions_repository, :events => events_repository}, nil, config, impression_manager, evaluation_producer, evaluator, SplitIoClient::Validators.new(config)) }
2219

23-
before do
24-
splits_repository.update([JSON.parse(splits,:symbolize_names => true)[:splits][2]], [], -1)
25-
end
20+
let(:splits) do
21+
File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/splits.json'))
22+
end
23+
24+
before do
25+
splits_repository.update([JSON.parse(splits,:symbolize_names => true)[:splits][2]], [], -1)
26+
end
2627

27-
it 'check getting treatments' do
28-
expect(split_client.get_treatment('key', 'testing222')).to eq('off')
29-
expect(split_client.get_treatments('key', ['testing222'])).to eq({:testing222 => 'off'})
30-
expect(split_client.get_treatment_with_config('key', 'testing222')).to eq({:treatment => 'off', :config => nil})
31-
expect(split_client.get_treatments_with_config('key', ['testing222'])).to eq({:testing222 => {:treatment => 'off', :config => nil}})
32-
expect(split_client.get_treatments_by_flag_set('key', 'set_1')).to eq({:testing222 => 'off'})
33-
expect(split_client.get_treatments_by_flag_sets('key', ['set_2'])).to eq({:testing222 => 'off'})
34-
expect(split_client.get_treatments_with_config_by_flag_set('key', 'set_1')).to eq({:testing222 => {:treatment => 'off', :config => nil}})
35-
expect(split_client.get_treatments_with_config_by_flag_sets('key', ['set_2'])).to eq({:testing222 => {:treatment => 'off', :config => nil}})
28+
it 'check getting treatments' do
29+
expect(split_client.get_treatment('key', 'testing222')).to eq('off')
30+
expect(split_client.get_treatments('key', ['testing222'])).to eq({:testing222 => 'off'})
31+
expect(split_client.get_treatment_with_config('key', 'testing222')).to eq({:treatment => 'off', :config => nil})
32+
expect(split_client.get_treatments_with_config('key', ['testing222'])).to eq({:testing222 => {:treatment => 'off', :config => nil}})
33+
expect(split_client.get_treatments_by_flag_set('key', 'set_1')).to eq({:testing222 => 'off'})
34+
expect(split_client.get_treatments_by_flag_sets('key', ['set_2'])).to eq({:testing222 => 'off'})
35+
expect(split_client.get_treatments_with_config_by_flag_set('key', 'set_1')).to eq({:testing222 => {:treatment => 'off', :config => nil}})
36+
expect(split_client.get_treatments_with_config_by_flag_sets('key', ['set_2'])).to eq({:testing222 => {:treatment => 'off', :config => nil}})
37+
end
38+
39+
it 'check track' do
40+
expect(split_client.track('key', 'account', 'event', 1)).to eq(true)
41+
end
3642
end
3743

38-
it 'check track' do
39-
expect(split_client.track('key', 'account', 'event', 1)).to eq(true)
44+
context 'post data before shutdown' do
45+
let(:splits) do
46+
File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/splits.json'))
47+
end
48+
let(:segment1) do
49+
File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/segment1.json'))
50+
end
51+
let(:segment2) do
52+
File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/segment2.json'))
53+
end
54+
let(:segment3) do
55+
File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/segment3.json'))
56+
end
57+
58+
it 'posting impressions and events' do
59+
stub_request(:get, 'https://sdk.split.io/api/splitChanges?since=-1')
60+
.to_return(status: 200, body: splits)
61+
stub_request(:post, 'https://events.split.io/api/events/bulk').to_return(status: 200, body: '')
62+
stub_request(:post, 'https://events.split.io/api/testImpressions/bulk').to_return(status: 200, body: '')
63+
stub_request(:post, 'https://telemetry.split.io/api/v1/metrics/config').to_return(status: 200, body: '')
64+
stub_request(:post, 'https://telemetry.split.io/api/v1/metrics/usage').to_return(status: 200, body: '')
65+
stub_request(:get, "https://sdk.split.io/api/splitChanges?since=1506703262916").to_return(status: 200, body: 'ok')
66+
stub_request(:get, "https://sdk.split.io/api/splitChanges?sets=set_3&since=1506703262916").to_return(status: 200, body: 'ok')
67+
mock_segment_changes('segment1', segment1, '-1')
68+
mock_segment_changes('segment1', segment1, '1470947453877')
69+
mock_segment_changes('segment2', segment2, '-1')
70+
mock_segment_changes('segment2', segment2, '1470947453878')
71+
mock_segment_changes('segment3', segment3, '-1')
72+
73+
factory5 = SplitIoClient::SplitFactory.new('test_api_key',
74+
features_refresh_rate: 9999,
75+
streaming_enabled: false)
76+
client5 = factory5.client
77+
client5.block_until_ready
78+
79+
for a in 1..100 do
80+
expect(client5.track('id' + a.to_s, 'account', 'event', 1)).to be_truthy
81+
end
82+
expect(client5.instance_variable_get(:@events_repository).empty?).to be(false)
83+
84+
expect(client5.get_treatment('nico_test', 'FACUNDO_TEST')).to eq 'on'
85+
expect(client5.instance_variable_get(:@impressions_repository).empty?).to be(false)
86+
87+
client5.destroy()
88+
89+
expect(client5.instance_variable_get(:@impressions_repository).empty?).to be(true)
90+
expect(client5.instance_variable_get(:@events_repository).empty?).to be(true)
91+
end
4092
end
93+
end
4194

95+
def mock_segment_changes(segment_name, segment_json, since)
96+
stub_request(:get, "https://sdk.split.io/api/segmentChanges/#{segment_name}?since=#{since}")
97+
.to_return(status: 200, body: segment_json)
4298
end

0 commit comments

Comments
 (0)