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 +4 -4
- data/.gitignore +4 -1
- data/Gemfile +1 -0
- data/Gemfile.lock +5 -1
- data/README.md +6 -6
- data/dev.md +1 -1
- data/lib/promoted/ruby/client.rb +109 -50
- data/lib/promoted/ruby/client/faraday_http_client.rb +1 -1
- data/lib/promoted/ruby/client/id_generator.rb +15 -0
- data/lib/promoted/ruby/client/pager.rb +57 -0
- data/lib/promoted/ruby/client/request_builder.rb +39 -8
- data/lib/promoted/ruby/client/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6339ed023cca804b02e1c118466d80dba1635d603f69c3d9a3789c9be8be1895
|
4
|
+
data.tar.gz: 75dce2d318c3d817bf0b4a6bcea20a4d6629cdf160e1a1f7973985c5cd8b57ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f73e120f23ec6e4c5049f26c6ca6d3418d660514d063e192631c9200fee5c165433e6ebb29858c7171a9c65b187eceae670ef57a2721835f733c2aaccf5e6aa
|
7
|
+
data.tar.gz: e3bad8867640b2ba17d92f7154366fa41a25b7eb16e9dac7a4b0a5ba9ffed52a1da749ee9aece0b6c05956158569539725306751baf576debac5fa5f6b922e6e
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
promoted-ruby-client (0.1.
|
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
|
32
|
-
:delivery_endpoint
|
33
|
-
:metrics_api_key
|
34
|
-
:delivery_api_key
|
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.
|
7
|
+
5. Run (using new output) `gem push promoted-ruby-client-0.1.10.gem`
|
8
8
|
6. Update README with new version.
|
data/lib/promoted/ruby/client.rb
CHANGED
@@ -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
|
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
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
83
|
-
|
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
|
-
|
129
|
+
delivery_request_builder.ensure_client_timestamp
|
97
130
|
|
98
131
|
response_insertions = []
|
99
132
|
cohort_membership_to_log = nil
|
100
|
-
|
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
|
-
|
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 !
|
167
|
+
if !insertions_from_delivery then
|
128
168
|
request_to_log = delivery_request_builder.request
|
129
|
-
|
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: !
|
160
|
-
include_request: !
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
254
|
-
|
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'
|
@@ -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
|
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
|
-
|
98
|
-
|
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] =
|
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"
|
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.
|
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-
|
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
|