Skip to content

Commit e3104bf

Browse files
committed
Changed hash to array to allow multiple feature flag records
1 parent f7bc08d commit e3104bf

File tree

4 files changed

+79
-61
lines changed

4 files changed

+79
-61
lines changed

lib/splitclient-rb/engine/impressions/unique_keys_tracker.rb

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -71,46 +71,70 @@ def add_or_update(feature_name, key)
7171
end
7272
end
7373

74+
def clear_cache
75+
uniques = @cache.clone
76+
keys_size = @keys_size
77+
@cache.clear
78+
@keys_size = 0
79+
80+
[uniques, keys_size]
81+
end
82+
7483
def send_bulk_data
7584
@semaphore.synchronize do
7685
return if @cache.empty?
7786

78-
uniques = @cache.clone
79-
keys_size = @keys_size
80-
@cache.clear
81-
@keys_size = 0
82-
87+
uniques, keys_size = clear_cache
8388
if keys_size <= @max_bulk_size
8489
@sender_adapter.record_uniques_key(uniques)
8590
return
86-
end
87-
88-
bulks = []
89-
uniques.each do |unique|
90-
bulks += check_keys_and_split_to_bulks(unique)
91-
end
9291

93-
bulks.each do |b|
94-
@sender_adapter.record_uniques_key(b)
9592
end
93+
bulks = flatten_bulks(uniques)
94+
bulks_to_post = group_bulks_by_max_size(bulks)
95+
@sender_adapter.record_uniques_key(bulks_to_post)
9696
end
9797
rescue StandardError => e
9898
@config.log_found_exception(__method__.to_s, e)
9999
end
100100

101-
def check_keys_and_split_to_bulks(unique)
102-
unique_updated = []
103-
unique.each do |_, value|
104-
if value.size > @max_bulk_size
105-
sub_bulks = SplitIoClient::Utilities.split_bulk_to_send(value, value.size / @max_bulk_size)
106-
sub_bulks.each do |sub_bulk|
107-
unique_updated.add({ key: sub_bulk })
108-
end
109-
break
101+
def group_bulks_by_max_size(bulks)
102+
current_size = 0
103+
bulks_to_post = Concurrent::Hash.new
104+
bulks.each do |bulk|
105+
key, value = bulk.first
106+
if (value.size + current_size) > @max_bulk_size
107+
@sender_adapter.record_uniques_key(bulks_to_post)
108+
bulks_to_post = Concurrent::Hash.new
109+
current_size = 0
110+
end
111+
bulks_to_post[key] = value
112+
current_size += value.size
113+
end
114+
115+
bulks_to_post
116+
end
117+
118+
def flatten_bulks(uniques)
119+
bulks = []
120+
uniques.each_key do |unique_key|
121+
bulks += check_keys_and_split_to_bulks(uniques[unique_key], unique_key)
122+
end
110123

124+
bulks
125+
end
126+
127+
def check_keys_and_split_to_bulks(value, key)
128+
unique_updated = []
129+
if value.size > @max_bulk_size
130+
sub_bulks = SplitIoClient::Utilities.split_bulk_to_send(value, @max_bulk_size)
131+
sub_bulks.each do |sub_bulk|
132+
unique_updated << { key => sub_bulk.to_set }
111133
end
112-
unique_updated.add({ key: value })
134+
return unique_updated
135+
113136
end
137+
unique_updated << { key => value }
114138

115139
unique_updated
116140
end

lib/splitclient-rb/utilitites.rb

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,12 @@ def randomize_interval(interval)
3838
interval * random_factor
3939
end
4040

41-
def split_bulk_to_send(hash, divisions)
42-
count = 0
43-
44-
hash.each_with_object([]) do |key_value, final|
45-
final[count % divisions] ||= {}
46-
final[count % divisions][key_value[0]] = key_value[1]
47-
count += 1
48-
end
49-
rescue StandardError
50-
[]
41+
def split_bulk_to_send(items, divisions)
42+
to_return = []
43+
items.to_a.each_slice(divisions) {|bulk|
44+
to_return.push(bulk.to_set)
45+
}
46+
to_return
5147
end
5248
end
5349
end

spec/engine/impressions/memory_unique_keys_tracker_spec.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,5 +146,26 @@
146146

147147
cache.clear
148148
end
149+
150+
it 'track - split chunks if above limit' do
151+
cache = Concurrent::Hash.new
152+
config.unique_keys_bulk_size = 1000
153+
tracker = subject.new(config, filter_adapter, sender_adapter_test, cache)
154+
155+
10.times { |i| expect(tracker.track("feature-test-#{i}", 'key_test')).to eq(true) }
156+
5.times { |i| expect(tracker.track("feature-test-1", "key_test-#{i}")).to eq(true) }
157+
158+
tracker.instance_variable_set(:@max_bulk_size, 5)
159+
tracker.send(:send_bulk_data)
160+
161+
result = sender_adapter_test.bulks
162+
expect(result[0].size).to eq(1)
163+
expect(result[1].size).to eq(1)
164+
expect(result[1]["feature-test-1"].size).to eq(5)
165+
expect(result[2].size).to eq(5)
166+
expect(result[3].size).to eq(4)
167+
168+
cache.clear
169+
end
149170
end
150171
end

spec/splitclient/utilities_spec.rb

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,37 +19,14 @@
1919
end
2020

2121
it 'split bulk of data - split equally' do
22-
hash = {}
22+
items = Set['feature', 'feature-1', 'feature-2', 'feature-3', 'feature-4', 'feature-5', 'feature-6']
2323

24-
i = 1
25-
while i <= 6
26-
hash["mauro-#{i}"] = Set.new(['feature', 'feature-1'])
27-
i += 1
28-
end
29-
30-
result = SplitIoClient::Utilities.split_bulk_to_send(hash, 3)
24+
result = SplitIoClient::Utilities.split_bulk_to_send(items, 3)
3125

26+
puts result
3227
expect(result.size).to eq 3
33-
expect(result[0].size).to eq 2
34-
expect(result[1].size).to eq 2
35-
expect(result[2].size).to eq 2
36-
end
37-
38-
it 'split bulk of data - split in 4 bulks' do
39-
hash = {}
40-
41-
i = 1
42-
while i <= 6
43-
hash["mauro-#{i}"] = 'feature-test'
44-
i += 1
45-
end
46-
47-
result = SplitIoClient::Utilities.split_bulk_to_send(hash, 4)
48-
49-
expect(result.size).to eq 4
50-
expect(result[0].size).to eq 2
51-
expect(result[1].size).to eq 2
28+
expect(result[0].size).to eq 3
29+
expect(result[1].size).to eq 3
5230
expect(result[2].size).to eq 1
53-
expect(result[3].size).to eq 1
5431
end
5532
end

0 commit comments

Comments
 (0)