splitclient-rb 5.1.3.pre.rc1-java → 5.1.3.pre.rc2-java

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 86614a077b8bb2e11605c201e8d7ce74fa53af08
4
- data.tar.gz: 5a775b16d37564ba6897dccd48d33472e7c4e1c3
3
+ metadata.gz: 6cb0311b168fb12d22bf8b707f307095383b9017
4
+ data.tar.gz: 90da2fd289742ed147bc2f1ba4604f94bf7b877f
5
5
  SHA512:
6
- metadata.gz: 22d0552dfae11161414e2a624ffaf8a4e7d402914541109da17f71178474b6627e6b5c5ef71622e56190cbb1b30cec8cba60c2bf39099b0019f8705ed7c4f71a
7
- data.tar.gz: 90e26ace99de500d55c05ddd9dc632b17e9d67bc8a1b5abbd1facae06110dfb8a43cb5443b9172293da7a25e1156a409b8e05406c7be5c1475ef307e33d70011
6
+ metadata.gz: ab58655555d5889e00b4eea5c1e7a851f412e3c6b23845eed34f2c44725762fbb518c3acbc9edf738ec37901049db3c23a61de28aaf132ab34bd6f39af83e5c8
7
+ data.tar.gz: 6067f1366ccbe092b5b4595d57b001c630c9f7d0e7101888f17bbc3670699bb002ba1a82ee479c03483aa35f5dc1caafe43e2ab6bc6447287aa92d6da91ea28a
data/.rubocop.yml CHANGED
@@ -1,3 +1,6 @@
1
+ Documentation:
2
+ Enabled: false
3
+
1
4
  Metrics/MethodLength:
2
5
  Max: 15
3
6
 
data/CHANGES.txt CHANGED
@@ -1,5 +1,5 @@
1
1
  5.1.3
2
- - Add cache wrapper to treatments and segments.
2
+ - Add cache wrapper to splits and segments.
3
3
 
4
4
  5.1.2 (October 26th, 2018)
5
5
  - Add input validation for client API methods
data/NEWS CHANGED
@@ -1,6 +1,6 @@
1
1
  5.1.3
2
2
 
3
- Add cache wrapper to treatments and segments.
3
+ Add cache wrapper to splits and segments.
4
4
 
5
5
  5.1.2
6
6
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
 
3
5
  module SplitIoClient
@@ -85,8 +87,8 @@ module SplitIoClient
85
87
  end
86
88
 
87
89
  # Set
88
- alias_method :initialize_set, :initialize_map
89
- alias_method :find_sets_by_prefix, :find_strings_by_prefix
90
+ alias initialize_set initialize_map
91
+ alias find_sets_by_prefix find_strings_by_prefix
90
92
 
91
93
  def add_to_set(key, val)
92
94
  @redis.sadd(key, val)
@@ -126,7 +128,7 @@ module SplitIoClient
126
128
  def get_from_queue(key, count)
127
129
  items = @redis.lrange(key, 0, count - 1)
128
130
  fetched_count = items.size
129
- items_to_remove = (fetched_count == count) ? count : fetched_count
131
+ items_to_remove = fetched_count == count ? count : fetched_count
130
132
 
131
133
  @redis.ltrim(key, items_to_remove, -1)
132
134
 
@@ -148,9 +150,9 @@ module SplitIoClient
148
150
  @redis.incrby(key, inc)
149
151
  end
150
152
 
151
- def pipelined(&block)
153
+ def pipelined
152
154
  @redis.pipelined do
153
- block.call
155
+ yield
154
156
  end
155
157
  end
156
158
 
@@ -159,6 +161,10 @@ module SplitIoClient
159
161
 
160
162
  keys.map { |key| @redis.del(key) }
161
163
  end
164
+
165
+ def expire(key, seconds)
166
+ @redis.expire(key, seconds)
167
+ end
162
168
  end
163
169
  end
164
170
  end
@@ -1,42 +1,44 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SplitIoClient
2
4
  module Cache
3
5
  module Repositories
4
6
  module Impressions
5
- class MemoryRepository
6
-
7
+ class MemoryRepository < ImpressionsRepository
7
8
  def initialize(adapter)
8
9
  @adapter = adapter
9
10
  end
10
11
 
11
12
  # Store impression data in the selected adapter
12
- def add(split_name, data)
13
- @adapter.add_to_queue(feature: split_name, impressions: data)
13
+ def add(matching_key, bucketing_key, split_name, treatment, time)
14
+ @adapter.add_to_queue(
15
+ m: metadata,
16
+ i: impression_data(
17
+ matching_key,
18
+ bucketing_key,
19
+ split_name,
20
+ treatment,
21
+ time
22
+ )
23
+ )
14
24
  rescue ThreadError # queue is full
15
25
  if random_sampler.rand(1..1000) <= 2 # log only 0.2 % of the time
16
- SplitIoClient.configuration.logger.warn("Dropping impressions. Current size is #{SplitIoClient.configuration.impressions_queue_size}. " \
17
- "Consider increasing impressions_queue_size")
26
+ SplitIoClient.configuration.logger.warn("Dropping impressions. Current size is \
27
+ #{SplitIoClient.configuration.impressions_queue_size}. " \
28
+ 'Consider increasing impressions_queue_size')
18
29
  end
19
30
  end
20
31
 
21
32
  def add_bulk(key, bucketing_key, treatments, time)
22
33
  treatments.each do |split_name, treatment|
23
- add(
24
- split_name,
25
- 'keyName' => key,
26
- 'bucketingKey' => bucketing_key,
27
- 'treatment' => treatment[:treatment],
28
- 'label' => SplitIoClient.configuration.labels_enabled ? treatment[:label] : nil,
29
- 'changeNumber' => treatment[:change_number],
30
- 'time' => time
31
- )
34
+ add(key, bucketing_key, split_name, treatment, time)
32
35
  end
33
36
  end
34
37
 
35
- def get_batch
36
- return [] if SplitIoClient.configuration.impressions_bulk_size == 0
37
- @adapter.get_batch(SplitIoClient.configuration.impressions_bulk_size).map do |impression|
38
- impression.update(ip: SplitIoClient.configuration.machine_ip)
39
- end
38
+ def batch
39
+ return [] if SplitIoClient.configuration.impressions_bulk_size.zero?
40
+
41
+ @adapter.get_batch(SplitIoClient.configuration.impressions_bulk_size)
40
42
  end
41
43
 
42
44
  private
@@ -1,75 +1,53 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SplitIoClient
2
4
  module Cache
3
5
  module Repositories
4
6
  module Impressions
5
- class RedisRepository < Repository
7
+ class RedisRepository < ImpressionsRepository
8
+ EXPIRE_SECONDS = 3600
6
9
 
7
10
  def initialize(adapter)
8
11
  @adapter = adapter
9
12
  end
10
13
 
11
- # Store impression data in Redis
12
- def add(split_name, data)
13
- @adapter.add_to_set(
14
- impressions_metrics_key("impressions.#{split_name}"),
15
- data.to_json
16
- )
14
+ def add(matching_key, bucketing_key, split_name, treatment, time)
15
+ add_bulk(matching_key, bucketing_key, { split_name => treatment }, time)
17
16
  end
18
17
 
19
- def add_bulk(key, bucketing_key, treatments, time)
20
- @adapter.redis.pipelined do
21
- treatments.each do |split_name, treatment|
22
- add(split_name,
23
- 'keyName' => key,
24
- 'bucketingKey' => bucketing_key,
25
- 'treatment' => treatment[:treatment],
26
- 'label' => SplitIoClient.configuration.labels_enabled ? treatment[:label] : nil,
27
- 'changeNumber' => treatment[:change_number],
28
- 'time' => time)
29
- end
18
+ def add_bulk(matching_key, bucketing_key, treatments, time)
19
+ impressions = treatments.map do |split_name, treatment|
20
+ {
21
+ m: metadata,
22
+ i: impression_data(
23
+ matching_key,
24
+ bucketing_key,
25
+ split_name,
26
+ treatment,
27
+ time
28
+ )
29
+ }.to_json
30
30
  end
31
- end
32
-
33
- # Get random impressions from redis in batches of size SplitIoClient.configuration.impressions_bulk_size,
34
- # delete fetched impressions afterwards
35
- def get_batch
36
- impressions = impression_keys.each_with_object([]) do |key, memo|
37
- ip = key.split('/')[-2] # 'prefix/sdk_lang/ip/impressions.name' -> ip
38
- if ip.nil?
39
- SplitIoClient.configuration.logger.warn("Impressions IP parse error for key: #{key}")
40
- next
41
- end
42
- split_name = key.split('.').last
43
- members = @adapter.random_set_elements(key, SplitIoClient.configuration.impressions_bulk_size)
44
- members.each do |impression|
45
- parsed_impression = JSON.parse(impression)
46
31
 
47
- memo << {
48
- feature: split_name.to_sym,
49
- impressions: parsed_impression,
50
- ip: ip
51
- }
52
- end
32
+ impressions_list_size = @adapter.add_to_queue(key, impressions)
53
33
 
54
- @adapter.delete_from_set(key, members)
34
+ # Synchronizer might not be running
35
+ @adapter.expire(key, EXPIRE_SECONDS) if impressions.size == impressions_list_size
36
+ end
55
37
 
38
+ def batch
39
+ @adapter.get_from_queue(key, SplitIoClient.configuration.impressions_bulk_size).map do |e|
40
+ impression = JSON.parse(e, symbolize_names: true)
41
+ impression[:i][:f] = impression[:i][:f].to_sym
42
+ impression
56
43
  end
57
- impressions
58
44
  rescue StandardError => e
59
45
  SplitIoClient.configuration.logger.error("Exception while clearing impressions cache: #{e}")
60
-
61
46
  []
62
47
  end
63
48
 
64
- private
65
-
66
- # Get all sets by prefix
67
- def impression_keys
68
- @adapter.find_sets_by_prefix("#{SplitIoClient.configuration.redis_namespace}/*/impressions.*")
69
- rescue StandardError => e
70
- SplitIoClient.configuration.logger.error("Exception while fetching impression_keys: #{e}")
71
-
72
- []
49
+ def key
50
+ @key ||= namespace_key('.impressions')
73
51
  end
74
52
  end
75
53
  end
@@ -1,18 +1,46 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SplitIoClient
2
4
  module Cache
3
5
  module Repositories
4
6
  # Repository which forwards impressions interface to the selected adapter
5
7
  class ImpressionsRepository < Repository
6
8
  extend Forwardable
7
- def_delegators :@adapter, :add, :add_bulk, :get_batch, :empty?
9
+ def_delegators :@adapter, :add, :add_bulk, :batch, :empty?
8
10
 
9
11
  def initialize(adapter)
10
12
  @adapter = case adapter.class.to_s
11
- when 'SplitIoClient::Cache::Adapters::MemoryAdapter'
12
- Repositories::Impressions::MemoryRepository.new(adapter)
13
- when 'SplitIoClient::Cache::Adapters::RedisAdapter'
14
- Repositories::Impressions::RedisRepository.new(adapter)
15
- end
13
+ when 'SplitIoClient::Cache::Adapters::MemoryAdapter'
14
+ Repositories::Impressions::MemoryRepository.new(adapter)
15
+ when 'SplitIoClient::Cache::Adapters::RedisAdapter'
16
+ Repositories::Impressions::RedisRepository.new(adapter)
17
+ end
18
+ end
19
+
20
+ protected
21
+
22
+ def impression_data(matching_key, bucketing_key, split_name, treatment, timestamp)
23
+ {
24
+ k: matching_key,
25
+ b: bucketing_key,
26
+ f: split_name,
27
+ t: treatment[:treatment],
28
+ r: applied_rule(treatment[:label]),
29
+ c: treatment[:change_number],
30
+ m: timestamp
31
+ }
32
+ end
33
+
34
+ def metadata
35
+ {
36
+ s: "#{SplitIoClient.configuration.language}-#{SplitIoClient.configuration.version}",
37
+ i: SplitIoClient.configuration.machine_ip,
38
+ n: SplitIoClient.configuration.machine_name
39
+ }
40
+ end
41
+
42
+ def applied_rule(label)
43
+ SplitIoClient.configuration.labels_enabled ? label : nil
16
44
  end
17
45
  end
18
46
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SplitIoClient
2
4
  module Cache
3
5
  module Senders
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SplitIoClient
2
4
  module Cache
3
5
  module Senders
@@ -7,29 +9,15 @@ module SplitIoClient
7
9
  end
8
10
 
9
11
  def call(raw_impressions)
10
- impressions = raw_impressions ? raw_impressions : @impressions_repository.get_batch
11
- formatted_impressions = []
12
+ impressions = raw_impressions || @impressions_repository.batch
12
13
  filtered_impressions = filter_impressions(impressions)
13
14
 
14
15
  return [] if impressions.empty? || filtered_impressions.empty?
15
16
 
16
17
  formatted_impressions = unique_features(filtered_impressions).each_with_object([]) do |feature, memo|
17
- ip = nil
18
- current_impressions =
19
- filtered_impressions
20
- .select { |impression| impression[:feature] == feature }
21
- .map do |impression|
22
- ip = impression[:ip]
23
- {
24
- keyName: impression[:impressions]['keyName'] || impression[:impressions]['key_name'],
25
- treatment: impression[:impressions]['treatment'],
26
- time: impression[:impressions]['time'],
27
- bucketingKey: impression[:impressions]['bucketingKey'] || impression[:impressions]['bucketing_key'],
28
- label: impression[:impressions]['label'],
29
- changeNumber: impression[:impressions]['changeNumber'] || impression[:impressions]['change_number'],
30
- }
31
- end
32
-
18
+ feature_impressions = feature_impressions(filtered_impressions, feature)
19
+ ip = feature_impressions.first[:m][:i]
20
+ current_impressions = current_impressions(feature_impressions)
33
21
  memo << {
34
22
  testName: feature.to_sym,
35
23
  keyImpressions: current_impressions,
@@ -42,8 +30,27 @@ module SplitIoClient
42
30
 
43
31
  private
44
32
 
33
+ def feature_impressions(filtered_impressions, feature)
34
+ filtered_impressions.select do |impression|
35
+ impression[:i][:f] == feature
36
+ end
37
+ end
38
+
39
+ def current_impressions(feature_impressions)
40
+ feature_impressions.map do |impression|
41
+ {
42
+ keyName: impression[:i][:k],
43
+ treatment: impression[:i][:t],
44
+ time: impression[:i][:m],
45
+ bucketingKey: impression[:i][:b],
46
+ label: impression[:i][:r],
47
+ changeNumber: impression[:i][:c]
48
+ }
49
+ end
50
+ end
51
+
45
52
  def unique_features(impressions)
46
- impressions.map { |impression| impression[:feature] }.uniq
53
+ impressions.map { |impression| impression[:i][:f] }.uniq
47
54
  end
48
55
 
49
56
  # Filter seen impressions by impression_hash
@@ -61,11 +68,11 @@ module SplitIoClient
61
68
  end
62
69
 
63
70
  def impression_hash(impression)
64
- "#{impression[:feature]}:" \
65
- "#{impression[:impressions]['keyName']}:" \
66
- "#{impression[:impressions]['bucketingKey']}:" \
67
- "#{impression[:impressions]['changeNumber']}:" \
68
- "#{impression[:impressions]['treatment']}"
71
+ "#{impression[:i][:f]}:" \
72
+ "#{impression[:i][:k]}:" \
73
+ "#{impression[:i][:b]}:" \
74
+ "#{impression[:i][:c]}:" \
75
+ "#{impression[:i][:t]}"
69
76
  end
70
77
  end
71
78
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SplitIoClient
2
4
  module Cache
3
5
  module Senders
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SplitIoClient
2
4
  module Cache
3
5
  module Senders
@@ -136,13 +136,12 @@ module SplitIoClient
136
136
 
137
137
  return if SplitIoClient.configuration.disable_impressions || !store_impressions
138
138
 
139
- @impressions_repository.add(split_name,
140
- 'keyName' => matching_key,
141
- 'bucketingKey' => bucketing_key,
142
- 'treatment' => treatment[:treatment],
143
- 'label' => SplitIoClient.configuration.labels_enabled ? treatment[:label] : nil,
144
- 'time' => time,
145
- 'changeNumber' => treatment[:change_number]
139
+ @impressions_repository.add(
140
+ matching_key,
141
+ bucketing_key,
142
+ split_name,
143
+ treatment,
144
+ time
146
145
  )
147
146
 
148
147
  route_impression(split_name, matching_key, bucketing_key, time, treatment, attributes)
@@ -1,3 +1,3 @@
1
1
  module SplitIoClient
2
- VERSION = '5.1.3.pre.rc1'
2
+ VERSION = '5.1.3.pre.rc2'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: splitclient-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.3.pre.rc1
4
+ version: 5.1.3.pre.rc2
5
5
  platform: java
6
6
  authors:
7
7
  - Split Software
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-11-05 00:00:00.000000000 Z
11
+ date: 2018-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement