promoted-ruby-client 0.1.6 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 30ba0e172809a6aa76284b4b88980fa45dea5b2bf28cdda4fbe8e672b7510a83
4
- data.tar.gz: e28586ed23f7db16b959bb9819072e502fc7af3805e68938f2bbf421fdc9e4d8
3
+ metadata.gz: 6339ed023cca804b02e1c118466d80dba1635d603f69c3d9a3789c9be8be1895
4
+ data.tar.gz: 75dce2d318c3d817bf0b4a6bcea20a4d6629cdf160e1a1f7973985c5cd8b57ae
5
5
  SHA512:
6
- metadata.gz: 4e6b42f73ff30726aa81af1c08b97a0cd0e0307685dec1f90dcce5d0d61d4009c3a2e6179af77a600038531101db187a83dc52f46a7c0ad4a99f7c6c2530b43e
7
- data.tar.gz: f3d304f0a2aad7acc15229750f97b021da4c0bfe8deae40c6ac1110bc7c1621ab0db19635464ba835e4e9a9ec07b9cfa0c231a9163fa0e1dcffeeebfdc1e51fc
6
+ metadata.gz: 4f73e120f23ec6e4c5049f26c6ca6d3418d660514d063e192631c9200fee5c165433e6ebb29858c7171a9c65b187eceae670ef57a2721835f733c2aaccf5e6aa
7
+ data.tar.gz: e3bad8867640b2ba17d92f7154366fa41a25b7eb16e9dac7a4b0a5ba9ffed52a1da749ee9aece0b6c05956158569539725306751baf576debac5fa5f6b922e6e
data/.gitignore CHANGED
@@ -57,4 +57,7 @@ build-iPhoneSimulator/
57
57
  # .rubocop-https?--*
58
58
 
59
59
  # IDE
60
- .vscode/
60
+ .vscode/
61
+
62
+ # Dev
63
+ dev/
data/Gemfile CHANGED
@@ -8,6 +8,7 @@ gemspec
8
8
  gem 'faraday', '~> 1.4.1'
9
9
  gem 'faraday_middleware'
10
10
  gem 'faraday-net_http'
11
+ gem 'net-http-persistent'
11
12
  gem 'concurrent-ruby', require: 'concurrent'
12
13
 
13
14
  group :development do
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- promoted-ruby-client (0.1.6)
4
+ promoted-ruby-client (0.1.10)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -10,6 +10,7 @@ GEM
10
10
  backport (1.2.0)
11
11
  benchmark (0.1.1)
12
12
  concurrent-ruby (1.1.9)
13
+ connection_pool (2.2.5)
13
14
  debase (0.2.5.beta2)
14
15
  debase-ruby_core_source (>= 0.10.12)
15
16
  debase-ruby_core_source (0.10.12)
@@ -38,6 +39,8 @@ GEM
38
39
  kramdown (~> 2.0)
39
40
  mini_portile2 (2.5.3)
40
41
  multipart-post (2.1.1)
42
+ net-http-persistent (4.0.1)
43
+ connection_pool (~> 2.2)
41
44
  nokogiri (1.11.7)
42
45
  mini_portile2 (~> 2.5.0)
43
46
  racc (~> 1.4)
@@ -116,6 +119,7 @@ DEPENDENCIES
116
119
  faraday-net_http
117
120
  faraday_middleware
118
121
  jaro_winkler
122
+ net-http-persistent
119
123
  promoted-ruby-client!
120
124
  rake (~> 10.0)
121
125
  rspec (~> 3.0)
data/README.md CHANGED
@@ -28,10 +28,10 @@ This client will suffice for building log requests. To send actually send traffi
28
28
 
29
29
  ```rb
30
30
  client = Promoted::Ruby::Client::PromotedClient.new({
31
- :metrics_endpoint = "https://<get this from Promoted>",
32
- :delivery_endpoint = "https://<get this from Promoted>",
33
- :metrics_api_key = "<get this from Promoted>",
34
- :delivery_api_key = "<get this from Promoted>"
31
+ :metrics_endpoint => "https://<get this from Promoted>",
32
+ :delivery_endpoint => "https://<get this from Promoted>",
33
+ :metrics_api_key => "<get this from Promoted>",
34
+ :delivery_api_key => "<get this from Promoted>"
35
35
  })
36
36
  ```
37
37
 
@@ -88,7 +88,7 @@ Field Name | Type | Optional? | Description
88
88
  ---------- | ---- | --------- | -----------
89
89
  ```:user_info``` | UserInfo | Yes | The user info structure.
90
90
  ```:insertion_id``` | String | Yes | Generated by the SDK (*do not set*)
91
- ```:request_id``` | String | Yes | Generated by the SDK (*do not set*)
91
+ ```:request_id``` | String | Yes | Generated by the SDK when needed (*do not set*)
92
92
  ```:content_id``` | String | No | Identifier for the content to be shown, must be set.
93
93
  ```:properties``` | Properties | Yes | Any additional custom properties to associate. For v1 integrations, it is fine not to fill in all the properties.
94
94
 
@@ -101,7 +101,7 @@ A request for content insertions.
101
101
  Field Name | Type | Optional? | Description
102
102
  ---------- | ---- | --------- | -----------
103
103
  ```:user_info``` | UserInfo | Yes | The user info structure.
104
- ```:request_id``` | String | Yes | Generated by the SDK (*do not set*)
104
+ ```:request_id``` | String | Yes | Generated by the SDK when needed (*do not set*)
105
105
  ```:use_case``` | String | Yes | One of the use case values, i.e. 'FEED' (see [constants.rb](https://github.com/promotedai/promoted-ruby-client/blob/main/lib/promoted/ruby/client/constants.rb)).
106
106
  ```:properties``` | Properties | Yes | Any additional custom properties to associate.
107
107
  ```:paging``` | Paging | Yes | Paging parameters (see TODO)
data/dev.md CHANGED
@@ -4,5 +4,5 @@
4
4
  2. Get credentials for deployment from 1password.
5
5
  3. Modify `promoted-ruby-client.gemspec`'s push block.
6
6
  4. Run `gem build promoted-ruby-client.gemspec` to generate `gem`.
7
- 5. Run (using new output) `gem push promoted-ruby-client-0.1.6.gem`
7
+ 5. Run (using new output) `gem push promoted-ruby-client-0.1.10.gem`
8
8
  6. Update README with new version.
@@ -19,8 +19,16 @@ module Promoted
19
19
  class Error < StandardError; end
20
20
 
21
21
  attr_reader :perform_checks, :default_only_log, :delivery_timeout_millis, :metrics_timeout_millis, :should_apply_treatment_func,
22
- :default_request_headers, :http_client
22
+ :default_request_headers, :http_client, :logger, :shadow_traffic_delivery_percent, :async_shadow_traffic
23
+
24
+ attr_accessor :request_logging_on, :enabled
23
25
 
26
+ ##
27
+ # Whether or not the client is currently enabled for execution.
28
+ def enabled?
29
+ @enabled
30
+ end
31
+
24
32
  ##
25
33
  # A common compact method implementation.
26
34
  def self.copy_and_remove_properties
@@ -39,7 +47,8 @@ module Promoted
39
47
  @perform_checks = params[:perform_checks]
40
48
  end
41
49
 
42
- @logger = params[:logger] # Example: Logger.new(STDERR, :progname => "promotedai")
50
+ @logger = params[:logger] # Example: Logger.new(STDERR, :progname => "promotedai")
51
+ @request_logging_on = params[:request_logging_on] || false
43
52
 
44
53
  @default_request_headers = params[:default_request_headers] || {}
45
54
  @metrics_api_key = params[:metrics_api_key] || ''
@@ -52,6 +61,7 @@ module Promoted
52
61
  raise ArgumentError.new("Invalid shadow_traffic_delivery_percent, must be between 0 and 1") if @shadow_traffic_delivery_percent < 0 || @shadow_traffic_delivery_percent > 1.0
53
62
 
54
63
  @sampler = Sampler.new
64
+ @pager = Pager.new
55
65
 
56
66
  # HTTP Client creation
57
67
  @delivery_endpoint = params[:delivery_endpoint] || DEFAULT_DELIVERY_ENDPOINT
@@ -66,21 +76,36 @@ module Promoted
66
76
  @http_client = FaradayHTTPClient.new
67
77
  @validator = Promoted::Ruby::Client::Validator.new
68
78
 
69
- # Thread pool to process delivery of shadow traffic. Will silently drop excess requests beyond the queue
70
- # size, and silently eat errors on the background threads.
71
- @pool = Concurrent::ThreadPoolExecutor.new(
72
- min_threads: 0,
73
- max_threads: 10,
74
- max_queue: 100,
75
- fallback_policy: :discard
76
- )
79
+ @async_shadow_traffic = true
80
+ if params[:async_shadow_traffic] != nil
81
+ @async_shadow_traffic = params[:async_shadow_traffic] || false
82
+ end
83
+
84
+ @pool = nil
85
+ if @async_shadow_traffic
86
+ # Thread pool to process delivery of shadow traffic. Will silently drop excess requests beyond the queue
87
+ # size, and silently eat errors on the background threads.
88
+ @pool = Concurrent::ThreadPoolExecutor.new(
89
+ min_threads: 0,
90
+ max_threads: 10,
91
+ max_queue: 100,
92
+ fallback_policy: :discard
93
+ )
94
+ end
95
+
96
+ @enabled = true
97
+ if params[:enabled] != nil
98
+ @enabled = params[:enabled] || false
99
+ end
77
100
  end
78
101
 
79
102
  ##
80
103
  # Politely shut down a Promoted client.
81
104
  def close
82
- @pool.shutdown
83
- @pool.wait_for_termination
105
+ if @pool
106
+ @pool.shutdown
107
+ @pool.wait_for_termination
108
+ end
84
109
  end
85
110
 
86
111
  ##
@@ -88,19 +113,34 @@ module Promoted
88
113
  def deliver args, headers={}
89
114
  args = Promoted::Ruby::Client::Util.translate_args(args)
90
115
 
116
+ # Respect the enabled state
117
+ if !@enabled
118
+ return {
119
+ insertion: @pager.apply_paging(args[:full_insertion], Promoted::Ruby::Client::INSERTION_PAGING_TYPE['UNPAGED'], args[:request][:paging])
120
+ # No log request returned when disabled
121
+ }
122
+ end
123
+
91
124
  delivery_request_builder = RequestBuilder.new
92
125
  delivery_request_builder.set_request_params(args)
93
126
 
94
127
  perform_common_checks!(args) if @perform_checks
95
128
 
96
- pre_delivery_fillin_fields delivery_request_builder
129
+ delivery_request_builder.ensure_client_timestamp
97
130
 
98
131
  response_insertions = []
99
132
  cohort_membership_to_log = nil
100
- insertions_from_promoted = false
133
+ insertions_from_delivery = false
101
134
 
102
135
  only_log = delivery_request_builder.only_log != nil ? delivery_request_builder.only_log : @default_only_log
103
136
  deliver_err = false
137
+
138
+ if !@pager.validate_paging(delivery_request_builder.full_insertion, delivery_request_builder.request[:paging])
139
+ # Invalid input, log and do SDK-side delivery.
140
+ @logger.warn("Invalid paging parameters") if @logger
141
+ only_log = true
142
+ end
143
+
104
144
  if !only_log
105
145
  cohort_membership_to_log = delivery_request_builder.new_cohort_membership_to_log
106
146
 
@@ -117,22 +157,16 @@ module Promoted
117
157
  @logger.error("Error calling delivery: " + err.message) if @logger
118
158
  end
119
159
 
120
- insertions_from_promoted = (response != nil && !deliver_err);
160
+ insertions_from_delivery = (response != nil && !deliver_err);
121
161
  response_insertions = delivery_request_builder.fill_details_from_response(
122
162
  response ? response[:insertion] : [])
123
163
  end
124
164
  end
125
165
 
126
166
  request_to_log = nil
127
- if !insertions_from_promoted then
167
+ if !insertions_from_delivery then
128
168
  request_to_log = delivery_request_builder.request
129
- size = delivery_request_builder.request.dig(:paging, :size)
130
- response_insertions = size != nil ? delivery_request_builder.full_insertion[0..size] : delivery_request_builder.full_insertion
131
- end
132
-
133
- if request_to_log
134
- request_to_log[:request_id] = SecureRandom.uuid if not request_to_log[:request_id]
135
- add_missing_ids_on_insertions! request_to_log, response_insertions
169
+ response_insertions = @pager.apply_paging(delivery_request_builder.full_insertion, Promoted::Ruby::Client::INSERTION_PAGING_TYPE['UNPAGED'], delivery_request_builder.request[:paging])
136
170
  end
137
171
 
138
172
  log_req = nil
@@ -150,14 +184,12 @@ module Promoted
150
184
  log_request_builder.platform_id = delivery_request_builder.platform_id
151
185
  log_request_builder.timing = delivery_request_builder.timing
152
186
  log_request_builder.user_info = delivery_request_builder.user_info
153
- pre_delivery_fillin_fields log_request_builder
154
-
155
187
 
156
188
  # On a successful delivery request, we don't log the insertions
157
189
  # or the request since they are logged on the server-side.
158
190
  log_req = log_request_builder.log_request_params(
159
- include_insertions: !insertions_from_promoted,
160
- include_request: !insertions_from_promoted)
191
+ include_insertions: !insertions_from_delivery,
192
+ include_request: !insertions_from_delivery)
161
193
  end
162
194
 
163
195
  client_response = {
@@ -173,6 +205,12 @@ module Promoted
173
205
  def prepare_for_logging args, headers={}
174
206
  args = Promoted::Ruby::Client::Util.translate_args(args)
175
207
 
208
+ if !@enabled
209
+ return {
210
+ insertion: args[:full_insertion]
211
+ }
212
+ end
213
+
176
214
  log_request_builder = RequestBuilder.new
177
215
 
178
216
  # Note: This method expects as JSON (string keys) but internally, RequestBuilder
@@ -188,7 +226,7 @@ module Promoted
188
226
  end
189
227
  end
190
228
 
191
- pre_delivery_fillin_fields log_request_builder
229
+ log_request_builder.ensure_client_timestamp
192
230
 
193
231
  if !shadow_traffic_err && should_send_as_shadow_traffic?
194
232
  deliver_shadow_traffic args, headers
@@ -211,29 +249,44 @@ module Promoted
211
249
  private
212
250
 
213
251
  def send_request payload, endpoint, timeout_millis, api_key, headers={}, send_async=false
252
+ resp = nil
253
+
214
254
  headers["x-api-key"] = api_key
215
255
  use_headers = @default_request_headers.merge headers
216
256
 
217
- if send_async
257
+ if @request_logging_on && @logger
258
+ @logger.info("promotedai") {
259
+ "Sending #{payload.to_json} to #{endpoint}"
260
+ }
261
+ end
262
+
263
+ if send_async && @pool
218
264
  @pool.post do
219
- @http_client.send(endpoint, timeout_millis, payload, use_headers)
265
+ start_time = Time.now
266
+ begin
267
+ resp = @http_client.send(endpoint, timeout_millis, payload, use_headers)
268
+ rescue Faraday::Error => err
269
+ @logger.warn("Async send_request failed with #{err}") if @logger
270
+ return
271
+ end
272
+
273
+ ellapsed_time = Time.now - start_time
274
+ @logger.debug("Async send_request completed in #{ellapsed_time.to_f * 1000} ms") if @logger
220
275
  end
221
276
  else
277
+ start_time = Time.now
222
278
  begin
223
- @http_client.send(endpoint, timeout_millis, payload, use_headers)
279
+ resp = @http_client.send(endpoint, timeout_millis, payload, use_headers)
224
280
  rescue Faraday::Error => err
281
+ @logger.warn("Sync send_request failed with #{err}") if @logger
225
282
  raise EndpointError.new(err)
226
283
  end
227
- end
228
- end
229
284
 
285
+ ellapsed_time = Time.now - start_time
286
+ @logger.debug("Sync send_request completed in #{ellapsed_time.to_f * 1000} ms") if @logger
287
+ end
230
288
 
231
- def add_missing_ids_on_insertions! request, insertions
232
- insertions.each do |insertion|
233
- insertion[:insertion_id] = SecureRandom.uuid if not insertion[:insertion_id]
234
- insertion[:session_id] = request[:session_id] if request[:session_id]
235
- insertion[:request_id] = request[:request_id] if request[:request_id]
236
- end
289
+ return resp
237
290
  end
238
291
 
239
292
  def should_send_as_shadow_traffic?
@@ -250,8 +303,19 @@ module Promoted
250
303
  delivery_request_params = delivery_request_builder.delivery_request_params(should_compact: false)
251
304
  delivery_request_params[:client_info][:traffic_type] = Promoted::Ruby::Client::TRAFFIC_TYPE['SHADOW']
252
305
 
253
- # Call Delivery API async (fire and forget)
254
- send_request(delivery_request_params, @delivery_endpoint, @delivery_timeout_millis, @delivery_api_key, headers, true)
306
+ # Call Delivery API and log/ignore errors.
307
+ start_time = Time.now
308
+ begin
309
+ send_request(delivery_request_params, @delivery_endpoint, @delivery_timeout_millis, @delivery_api_key, headers, @async_shadow_traffic)
310
+ rescue StandardError => err
311
+ @logger.warn("Shadow traffic call failed with #{err}") if @logger
312
+ return
313
+ end
314
+
315
+ if !@async_shadow_traffic
316
+ ellapsed_time = Time.now - start_time
317
+ @logger.info("Shadow traffic call completed in #{ellapsed_time.to_f * 1000} ms") if @logger
318
+ end
255
319
  end
256
320
 
257
321
  def perform_common_checks!(req)
@@ -272,14 +336,7 @@ module Promoted
272
336
  return true if !cohort_membership[:arm]
273
337
  return cohort_membership[:arm] != Promoted::Ruby::Client::COHORT_ARM['CONTROL']
274
338
  end
275
- end
276
-
277
- # TODO: This probably just goes better in the RequestBuilder class.
278
- def pre_delivery_fillin_fields(log_request_builder)
279
- if log_request_builder.timing[:client_log_timestamp].nil?
280
- log_request_builder.timing[:client_log_timestamp] = Time.now.to_i
281
- end
282
- end
339
+ end
283
340
  end
284
341
  end
285
342
  end
@@ -287,7 +344,9 @@ end
287
344
 
288
345
  # dependent /libs
289
346
  require "promoted/ruby/client/request_builder"
347
+ require "promoted/ruby/client/pager"
290
348
  require "promoted/ruby/client/sampler"
291
349
  require "promoted/ruby/client/util"
292
350
  require "promoted/ruby/client/validator"
293
- require 'securerandom'
351
+ require 'securerandom'
352
+ require 'time'
@@ -11,7 +11,7 @@ module Promoted
11
11
  f.request :json
12
12
  f.request :retry, max: 3
13
13
  f.use Faraday::Response::RaiseError # raises on 4xx and 5xx responses
14
- f.adapter :net_http
14
+ f.adapter :net_http_persistent
15
15
  end
16
16
  end
17
17
 
@@ -0,0 +1,15 @@
1
+ module Promoted
2
+ module Ruby
3
+ module Client
4
+ class IdGenerator
5
+ def initialize;end
6
+
7
+ def newID
8
+ SecureRandom.uuid
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ require 'securerandom'
@@ -0,0 +1,57 @@
1
+ module Promoted
2
+ module Ruby
3
+ module Client
4
+ class Pager
5
+ def validate_paging (insertions, paging)
6
+ if paging && paging[:offset]
7
+ return paging[:offset] < insertions.length
8
+ end
9
+ return true
10
+ end
11
+
12
+ def apply_paging (insertions, insertion_page_type, paging = nil)
13
+ # This is invalid input, stop it before it goes to the server.
14
+ if !validate_paging(insertions, paging)
15
+ return []
16
+ end
17
+
18
+ if !paging
19
+ paging = {
20
+ :offset => 0,
21
+ :size => insertions.length
22
+ }
23
+ end
24
+
25
+ offset = [0, paging[:offset]].max
26
+
27
+ index = offset
28
+ if insertion_page_type == Promoted::Ruby::Client::INSERTION_PAGING_TYPE['PRE_PAGED']
29
+ # When insertions are pre-paged, we don't use offset to
30
+ # window into the provided insertions, although we do use it when
31
+ # assigning positions.
32
+ index = 0
33
+ end
34
+
35
+ size = paging[:size]
36
+ if size <= 0
37
+ size = insertions.length
38
+ end
39
+
40
+ final_insertion_size = [size, insertions.length].min
41
+ insertion_page = Array.new(final_insertion_size)
42
+ 0.upto(final_insertion_size - 1) {|i|
43
+ insertion = insertions[index]
44
+ if insertion[:position] == nil
45
+ insertion[:position] = offset
46
+ end
47
+ insertion_page[i] = insertion
48
+ index = index + 1
49
+ offset = offset + 1
50
+ }
51
+
52
+ return insertion_page
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -8,7 +8,13 @@ module Promoted
8
8
 
9
9
  attr_accessor :timing, :user_info, :platform_id
10
10
 
11
- def initialize;end
11
+ def initialize args = {}
12
+ if args[:id_generator]
13
+ @id_generator = args[:id_generator]
14
+ else
15
+ @id_generator = IdGenerator.new
16
+ end
17
+ end
12
18
 
13
19
  # Populates request parameters from the given arguments, presumed to be a hash of symbols.
14
20
  def set_request_params args = {}
@@ -21,11 +27,13 @@ module Promoted
21
27
  @view_id = request[:view_id]
22
28
  @use_case = Promoted::Ruby::Client::USE_CASES[request[:use_case]] || Promoted::Ruby::Client::USE_CASES['UNKNOWN_USE_CASE']
23
29
  @full_insertion = args[:full_insertion]
24
- @request_id = SecureRandom.uuid
25
30
  @user_info = request[:user_info] || { :user_id => nil, :log_user_id => nil}
26
31
  @timing = request[:timing] || { :client_log_timestamp => Time.now.to_i }
27
32
  @to_compact_metrics_insertion_func = args[:to_compact_metrics_insertion_func]
28
33
  @to_compact_delivery_insertion_func = args[:to_compact_delivery_insertion_func]
34
+
35
+ # If the user didn't create a client request id, we do it for them.
36
+ request[:client_request_id] = request[:client_request_id] || @id_generator.newID
29
37
  end
30
38
 
31
39
  # Only used in delivery
@@ -50,13 +58,13 @@ module Promoted
50
58
  timing: timing,
51
59
  client_info: @client_info.merge({ :client_type => Promoted::Ruby::Client::CLIENT_TYPE['PLATFORM_SERVER'] }),
52
60
  platform_id: @platform_id,
53
- request_id: @request_id,
54
61
  view_id: @view_id,
55
62
  session_id: @session_id,
56
63
  use_case: @use_case,
57
64
  search_query: request[:search_query],
58
65
  properties: request[:properties],
59
- paging: request[:paging]
66
+ paging: request[:paging],
67
+ client_request_id: request[:client_request_id]
60
68
  }
61
69
  params[:insertion] = should_compact ? compact_delivery_insertions : full_insertion
62
70
 
@@ -94,8 +102,17 @@ module Promoted
94
102
  cohort_membership: @experiment,
95
103
  client_info: @client_info
96
104
  }
97
- params[:request] = [request] if include_request
98
- params[:insertion] = compact_metrics_insertions if include_insertions
105
+
106
+ # Log request allows for multiple requests but here we only send one.
107
+ if include_request
108
+ request[:request_id] = request[:request_id] || @id_generator.newID
109
+ params[:request] = [request]
110
+ end
111
+
112
+ if include_insertions
113
+ params[:insertion] = compact_metrics_insertions if include_insertions
114
+ add_missing_ids_on_insertions! request, params[:insertion]
115
+ end
99
116
 
100
117
  params.clean!
101
118
  end
@@ -108,6 +125,12 @@ module Promoted
108
125
  end
109
126
  end
110
127
 
128
+ def ensure_client_timestamp
129
+ if timing[:client_log_timestamp].nil?
130
+ timing[:client_log_timestamp] = Time.now.to_i
131
+ end
132
+ end
133
+
111
134
  # TODO: This looks overly complicated.
112
135
  def compact_metrics_insertions
113
136
  @insertion = [] # insertion should be set according to the compact insertion
@@ -126,7 +149,7 @@ module Promoted
126
149
  insertion_obj = Hash[insertion_obj]
127
150
  insertion_obj[:user_info] = user_info
128
151
  insertion_obj[:timing] = timing
129
- insertion_obj[:insertion_id] = SecureRandom.uuid # generate random UUID
152
+ insertion_obj[:insertion_id] = @id_generator.newID
130
153
  insertion_obj[:request_id] = request_id
131
154
  insertion_obj[:position] = offset + index
132
155
  insertion_obj = @to_compact_metrics_insertion_func.call(insertion_obj) if @to_compact_metrics_insertion_func
@@ -137,6 +160,14 @@ module Promoted
137
160
 
138
161
  private
139
162
 
163
+ def add_missing_ids_on_insertions! request, insertions
164
+ insertions.each do |insertion|
165
+ insertion[:insertion_id] = @id_generator.newID if not insertion[:insertion_id]
166
+ insertion[:session_id] = request[:session_id] if request[:session_id]
167
+ insertion[:request_id] = request[:request_id] if request[:request_id]
168
+ end
169
+ end
170
+
140
171
  # A list of the response Insertions. This client expects lists to be truncated
141
172
  # already to request.paging.size. If not truncated, this client will truncate
142
173
  # the list.
@@ -148,6 +179,6 @@ module Promoted
148
179
  end
149
180
  end
150
181
 
151
- require 'securerandom'
152
182
  require "promoted/ruby/client/constants"
153
183
  require "promoted/ruby/client/extensions"
184
+ require "promoted/ruby/client/id_generator"
@@ -1,7 +1,7 @@
1
1
  module Promoted
2
2
  module Ruby
3
3
  module Client
4
- VERSION = "0.1.6"
4
+ VERSION = "0.1.10"
5
5
  end
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: promoted-ruby-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - scottmcmaster
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-07-07 00:00:00.000000000 Z
11
+ date: 2021-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -75,6 +75,8 @@ files:
75
75
  - lib/promoted/ruby/client/errors.rb
76
76
  - lib/promoted/ruby/client/extensions.rb
77
77
  - lib/promoted/ruby/client/faraday_http_client.rb
78
+ - lib/promoted/ruby/client/id_generator.rb
79
+ - lib/promoted/ruby/client/pager.rb
78
80
  - lib/promoted/ruby/client/request_builder.rb
79
81
  - lib/promoted/ruby/client/sampler.rb
80
82
  - lib/promoted/ruby/client/util.rb