promoted-ruby-client 0.1.23 → 1.0.0
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 +4 -4
- data/.gitignore +3 -1
- data/Gemfile.lock +1 -1
- data/README.md +9 -23
- data/dev.md +1 -1
- data/lib/promoted/ruby/client/request_builder.rb +33 -86
- data/lib/promoted/ruby/client/validator.rb +10 -10
- data/lib/promoted/ruby/client/version.rb +2 -1
- data/lib/promoted/ruby/client.rb +43 -62
- data/promoted-ruby-client.gemspec +1 -1
- metadata +2 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3f9ec2c51749dd3819e71b93784a0eea77f4f11b0117ad21c44ae976a2b1d96
|
4
|
+
data.tar.gz: a507c5f00b3e3cfc8116c67f2413f51e6a9b45827f991ad44953c36b5c44b453
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 580f2c7e11d8cc30e1c2d23f2c0b57f311597af695d0179a4d32149d1e4e3723d122e8f2783ce4e1e9b0d09374779a029091106c10612920b7d0c5e942b35ebe
|
7
|
+
data.tar.gz: 3a75185fe166e28b551eb82fd7cbcb51cf92c1fb8fdf7a1266bbb46715fd8d190ef9df75da5ab438991dde5352c4802abd8d3ee68abf27400aa58ca40037cb8e
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -54,6 +54,7 @@ Name | Type | Description
|
|
54
54
|
```:default_only_log``` | Boolean | If true, the ```deliver``` method will not direct traffic to Delivery API but rather return a request suitable for logging. Defaults to false.
|
55
55
|
```:should_apply_treatment_func``` | Proc | Called during delivery, accepts an experiment and returns a Boolean indicating whether the request should be considered part of the control group (false) or in the experiment (true). If nil, the default behavior of checking the experiement ```:arm``` is applied.
|
56
56
|
```:warmup``` | Boolean | If true, the client will prime the `Net::HTTP::Persistent` connection pool on construction; this can make the first few calls to Promoted complete faster. Defaults to false.
|
57
|
+
```:max_request_insertions``` | Number | Maximum number of request insertions that will be passed to Delivery API on a single request (any more will be truncated by the SDK). Defaults to 1000.
|
57
58
|
|
58
59
|
## Data Types
|
59
60
|
|
@@ -152,6 +153,7 @@ Field Name | Type | Optional? | Description
|
|
152
153
|
```:user_agent``` | String | Yes | Browser user agent string
|
153
154
|
```:viewport_size``` | Size | Yes | Size of the browser viewport
|
154
155
|
```:client_hints``` | ClientHints | Yes | HTTP client hints structure
|
156
|
+
```referrer``` | String | Yes | Request referrer
|
155
157
|
---
|
156
158
|
### Device
|
157
159
|
Information about the user's device.
|
@@ -180,13 +182,6 @@ Field Name | Type | Optional? | Description
|
|
180
182
|
```:paging``` | Paging | Yes | Paging parameters (see TODO)
|
181
183
|
```:device``` | Device | Yes | Device information (as available)
|
182
184
|
---
|
183
|
-
### MetricsRequest
|
184
|
-
Input to ```prepare_for_logging```
|
185
|
-
Field Name | Type | Optional? | Description
|
186
|
-
---------- | ---- | --------- | -----------
|
187
|
-
```:request``` | Request | No | The underlying request for content.
|
188
|
-
```:full_insertion``` | [] of Insertion | No | The proposed list of insertions.
|
189
|
-
---
|
190
185
|
|
191
186
|
### DeliveryRequest
|
192
187
|
Input to ```deliver```
|
@@ -194,7 +189,6 @@ Field Name | Type | Optional? | Description
|
|
194
189
|
---------- | ---- | --------- | -----------
|
195
190
|
```:experiment``` | CohortMembership | Yes | A cohort to evaluation in experimentation.
|
196
191
|
```:request``` | Request | No | The underlying request for content.
|
197
|
-
```:full_insertion``` | [] of Insertion | No | The proposed list of insertions with all metadata, will be compacted before forwarding to Promoted.
|
198
192
|
```:only_log``` | Boolean | Yes | Defaults to false. Set to true to override whether Delivery API is called for this request.
|
199
193
|
---
|
200
194
|
|
@@ -286,28 +280,20 @@ metrics_request = {
|
|
286
280
|
:struct => {
|
287
281
|
:active => true
|
288
282
|
}
|
289
|
-
}
|
283
|
+
},
|
284
|
+
:insertion => insertions
|
290
285
|
},
|
291
|
-
:
|
286
|
+
:only_log => true,
|
292
287
|
}
|
293
288
|
|
294
|
-
# OPTIONAL: You can pass a custom function to "compact" insertions before metrics logging.
|
295
|
-
# Note that the PromotedClient has a class method helper, remove_all_properties, that does
|
296
|
-
# an implementation of this, returning nil to remove ALL properties.
|
297
|
-
to_compact_metrics_properties_func = Proc.new do |properties|
|
298
|
-
properties[:struct].delete(:active)
|
299
|
-
properties
|
300
|
-
end
|
301
|
-
# metrics_request[:to_compact_metrics_properties_func] = to_compact_metrics_properties_func
|
302
|
-
|
303
289
|
# Create a client
|
304
290
|
client = Promoted::Ruby::Client::PromotedClient.new
|
305
291
|
|
306
292
|
# Build a log request
|
307
|
-
|
293
|
+
client_response = client.deliver(metrics_request)
|
308
294
|
|
309
295
|
# Log (assuming you have configured your client with a :metrics_endpoint)
|
310
|
-
client.send_log_request(log_request)
|
296
|
+
client.send_log_request(client_response[:log_request]) if client_response[:log_request]
|
311
297
|
```
|
312
298
|
|
313
299
|
## Delivery API
|
@@ -330,9 +316,9 @@ delivery_request = {
|
|
330
316
|
:struct => {
|
331
317
|
:active => true
|
332
318
|
}
|
333
|
-
}
|
319
|
+
},
|
320
|
+
:insertion => insertions,
|
334
321
|
},
|
335
|
-
:full_insertion => insertions,
|
336
322
|
:only_log => false
|
337
323
|
}
|
338
324
|
|
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.
|
7
|
+
5. Run (using new output) `gem push promoted-ruby-client-1.0.0.gem`
|
8
8
|
6. Update README with new version.
|
@@ -3,10 +3,9 @@ module Promoted
|
|
3
3
|
module Client
|
4
4
|
class RequestBuilder
|
5
5
|
attr_reader :session_id, :only_log, :experiment, :client_info, :device,
|
6
|
-
:view_id, :insertion, :
|
7
|
-
:request_id, :full_insertion, :use_case, :request, :to_compact_metrics_properties_func
|
6
|
+
:view_id, :insertion, :request_id, :use_case, :request
|
8
7
|
|
9
|
-
attr_accessor :timing, :user_info, :platform_id
|
8
|
+
attr_accessor :timing, :user_info, :platform_id, :insertion
|
10
9
|
|
11
10
|
def initialize args = {}
|
12
11
|
if args[:id_generator]
|
@@ -27,11 +26,9 @@ module Promoted
|
|
27
26
|
@device = request[:device] || {}
|
28
27
|
@view_id = request[:view_id]
|
29
28
|
@use_case = Promoted::Ruby::Client::USE_CASES[request[:use_case]] || Promoted::Ruby::Client::USE_CASES['UNKNOWN_USE_CASE']
|
30
|
-
@
|
29
|
+
@insertion = request[:insertion] || []
|
31
30
|
@user_info = request[:user_info] || { :user_id => nil, :log_user_id => nil}
|
32
|
-
@timing = request[:timing] || { :client_log_timestamp => Time.now.to_i }
|
33
|
-
@to_compact_metrics_properties_func = args[:to_compact_metrics_properties_func]
|
34
|
-
@to_compact_delivery_properties_func = args[:to_compact_delivery_properties_func]
|
31
|
+
@timing = request[:timing] || { :client_log_timestamp => (Time.now.to_f * 1000).to_i }
|
35
32
|
|
36
33
|
# If the user didn't create a client request id, we do it for them.
|
37
34
|
request[:client_request_id] = request[:client_request_id] || @id_generator.newID
|
@@ -68,7 +65,7 @@ module Promoted
|
|
68
65
|
paging: request[:paging],
|
69
66
|
client_request_id: client_request_id
|
70
67
|
}
|
71
|
-
params[:insertion] =
|
68
|
+
params[:insertion] = insertion
|
72
69
|
|
73
70
|
params.clean!
|
74
71
|
end
|
@@ -81,7 +78,7 @@ module Promoted
|
|
81
78
|
response_insertions = []
|
82
79
|
end
|
83
80
|
|
84
|
-
props = @
|
81
|
+
props = @insertion.each_with_object({}) do |insertion, hash|
|
85
82
|
if insertion.has_key?(:properties)
|
86
83
|
# Don't add nil properties to response insertions.
|
87
84
|
hash[insertion[:content_id]] = insertion[:properties]
|
@@ -100,17 +97,12 @@ module Promoted
|
|
100
97
|
filled_in_copy
|
101
98
|
end
|
102
99
|
|
103
|
-
def log_request_params(
|
100
|
+
def log_request_params(include_delivery_log:, exec_server:)
|
104
101
|
params = {
|
105
102
|
user_info: user_info,
|
106
103
|
timing: timing,
|
107
104
|
client_info: merge_client_info_defaults,
|
108
105
|
device: @device,
|
109
|
-
delivery_log: [{
|
110
|
-
execution: {
|
111
|
-
execution_server: Promoted::Ruby::Client::EXECUTION_SERVER['SDK']
|
112
|
-
}
|
113
|
-
}]
|
114
106
|
}
|
115
107
|
|
116
108
|
if @experiment
|
@@ -118,81 +110,51 @@ module Promoted
|
|
118
110
|
end
|
119
111
|
|
120
112
|
# Log request allows for multiple requests but here we only send one.
|
121
|
-
if
|
113
|
+
if include_delivery_log
|
122
114
|
request[:request_id] = request[:request_id] || @id_generator.newID
|
123
|
-
# Set request on delivery log.
|
124
|
-
params[:delivery_log][0][:request] = request
|
125
|
-
end
|
126
115
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
116
|
+
params[:delivery_log] = [{
|
117
|
+
execution: {
|
118
|
+
execution_server: exec_server,
|
119
|
+
server_version: Promoted::Ruby::Client::SERVER_VERSION
|
120
|
+
},
|
121
|
+
request: request,
|
122
|
+
response: {
|
123
|
+
insertion: response_insertion
|
124
|
+
}
|
125
|
+
}]
|
126
|
+
|
127
|
+
add_missing_insertion_ids! params[:delivery_log][0][:response][:insertion]
|
133
128
|
end
|
134
129
|
|
135
130
|
params.clean!
|
136
131
|
end
|
137
132
|
|
138
|
-
def compact_one_insertion(insertion, compact_func)
|
139
|
-
return insertion if (!compact_func || !insertion[:properties])
|
140
|
-
|
141
|
-
# Only need a copy if there are properties to compact.
|
142
|
-
compact_insertion = insertion.dup
|
143
|
-
|
144
|
-
# Let the custom function work with a deep copy of the properties.
|
145
|
-
# There's really no way to work with a shallow copy and still be able
|
146
|
-
# to restore the correct insertion properties after a call to delivery.
|
147
|
-
new_props = Marshal.load(Marshal.dump(insertion[:properties]))
|
148
|
-
compact_insertion[:properties] = compact_func.call(new_props)
|
149
|
-
compact_insertion.clean!
|
150
|
-
return compact_insertion
|
151
|
-
end
|
152
|
-
|
153
|
-
def insertions_with_compact_props(compact_func)
|
154
|
-
if !compact_func
|
155
|
-
# Nothing to do, avoid copying the whole array.
|
156
|
-
full_insertion
|
157
|
-
else
|
158
|
-
compact_insertions = Array.new(full_insertion.length)
|
159
|
-
full_insertion.each_with_index {|insertion, index|
|
160
|
-
compact_insertions[index] = compact_one_insertion(insertion, compact_func)
|
161
|
-
}
|
162
|
-
compact_insertions
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
133
|
def ensure_client_timestamp
|
167
134
|
if timing[:client_log_timestamp].nil?
|
168
|
-
timing[:client_log_timestamp] = Time.now.to_i
|
135
|
+
timing[:client_log_timestamp] = (Time.now.to_f * 1000).to_i
|
169
136
|
end
|
170
137
|
end
|
171
138
|
|
172
|
-
|
173
|
-
|
174
|
-
@insertion = [] # insertion should be set according to the compact insertion
|
139
|
+
def response_insertion
|
140
|
+
@response_insertions = []
|
175
141
|
paging = request[:paging] || {}
|
176
142
|
size = paging[:size] ? paging[:size].to_i : 0
|
177
143
|
if size <= 0
|
178
|
-
size =
|
144
|
+
size = insertion.length()
|
179
145
|
end
|
180
146
|
offset = paging[:offset] ? paging[:offset].to_i : 0
|
181
147
|
|
182
|
-
|
148
|
+
insertion.each_with_index do |insertion_obj, index|
|
183
149
|
# TODO - this does not look performant.
|
184
|
-
break if @
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
insertion_obj = compact_one_insertion(insertion_obj, @to_compact_metrics_properties_func)
|
193
|
-
@insertion << insertion_obj.clean!
|
194
|
-
end
|
195
|
-
@insertion
|
150
|
+
break if @response_insertions.length() >= size
|
151
|
+
response_insertion = Hash[]
|
152
|
+
response_insertion[:content_id] = insertion_obj[:content_id]
|
153
|
+
response_insertion[:position] = offset + index
|
154
|
+
response_insertion[:insertion_id] = insertion_obj[:insertion_id]
|
155
|
+
@response_insertions << response_insertion.clean!
|
156
|
+
end
|
157
|
+
@response_insertions
|
196
158
|
end
|
197
159
|
|
198
160
|
def add_missing_insertion_ids! insertions
|
@@ -213,21 +175,6 @@ module Promoted
|
|
213
175
|
:traffic_type => Promoted::Ruby::Client::TRAFFIC_TYPE['PRODUCTION']
|
214
176
|
})
|
215
177
|
end
|
216
|
-
|
217
|
-
def add_missing_ids_on_insertions! request, insertions
|
218
|
-
insertions.each do |insertion|
|
219
|
-
insertion[:session_id] = request[:session_id] if request[:session_id]
|
220
|
-
insertion[:request_id] = request[:request_id] if request[:request_id]
|
221
|
-
end
|
222
|
-
add_missing_insertion_ids! insertions
|
223
|
-
end
|
224
|
-
|
225
|
-
# A list of the response Insertions. This client expects lists to be truncated
|
226
|
-
# already to request.paging.size. If not truncated, this client will truncate
|
227
|
-
# the list.
|
228
|
-
def insertion
|
229
|
-
@insertion
|
230
|
-
end
|
231
178
|
end
|
232
179
|
end
|
233
180
|
end
|
@@ -99,6 +99,7 @@ module Promoted
|
|
99
99
|
},
|
100
100
|
{
|
101
101
|
:name => :insertion,
|
102
|
+
:required => true,
|
102
103
|
:type => Array
|
103
104
|
}
|
104
105
|
]
|
@@ -115,6 +116,7 @@ module Promoted
|
|
115
116
|
end
|
116
117
|
end
|
117
118
|
|
119
|
+
# TODO - delete?
|
118
120
|
def validate_metrics_request!(metrics_req)
|
119
121
|
validate_fields!(
|
120
122
|
metrics_req,
|
@@ -123,31 +125,29 @@ module Promoted
|
|
123
125
|
{
|
124
126
|
:name => :request,
|
125
127
|
:required => true
|
126
|
-
},
|
127
|
-
{
|
128
|
-
:name => :full_insertion,
|
129
|
-
:required => true,
|
130
|
-
:type => Array
|
131
128
|
}
|
132
129
|
]
|
133
130
|
)
|
134
131
|
|
135
132
|
validate_request!(metrics_req[:request])
|
136
|
-
metrics_req[:full_insertion].each {|ins|
|
137
|
-
validate_insertion! ins
|
138
|
-
}
|
139
133
|
end
|
140
134
|
|
141
135
|
def check_that_log_ids_not_set! req
|
136
|
+
raise ValidationError.new("Request should be set") if !req[:request]
|
142
137
|
raise ValidationError.new("Request.requestId should not be set") if req.dig(:request, :request_id)
|
143
|
-
raise ValidationError.new("Do not set Request.insertion. Set full_insertion.") if req[:insertion]
|
144
138
|
|
145
|
-
req[:
|
139
|
+
req[:request][:insertion].each do |insertion_hash|
|
146
140
|
raise ValidationError.new("Insertion.requestId should not be set") if insertion_hash[:request_id]
|
147
141
|
raise ValidationError.new("'Insertion.insertionId should not be set") if insertion_hash[:insertion_id]
|
148
142
|
end
|
149
143
|
end
|
150
144
|
|
145
|
+
def check_that_content_ids_are_set! req
|
146
|
+
req[:request][:insertion].each do |insertion_hash|
|
147
|
+
raise ValidationError.new("Insertion.contentId should be set") if !insertion_hash[:content_id] || insertion_hash[:content_id].empty?
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
151
|
private
|
152
152
|
|
153
153
|
def validate_fields!(obj, obj_name, fields)
|
data/lib/promoted/ruby/client.rb
CHANGED
@@ -8,6 +8,7 @@ module Promoted
|
|
8
8
|
|
9
9
|
DEFAULT_DELIVERY_TIMEOUT_MILLIS = 250
|
10
10
|
DEFAULT_METRICS_TIMEOUT_MILLIS = 3000
|
11
|
+
DEFAULT_MAX_REQUEST_INSERTIONS = 1000
|
11
12
|
DEFAULT_DELIVERY_ENDPOINT = "http://delivery.example.com"
|
12
13
|
DEFAULT_METRICS_ENDPOINT = "http://metrics.example.com"
|
13
14
|
|
@@ -20,7 +21,7 @@ module Promoted
|
|
20
21
|
|
21
22
|
attr_reader :perform_checks, :default_only_log, :delivery_timeout_millis, :metrics_timeout_millis, :should_apply_treatment_func,
|
22
23
|
:default_request_headers, :http_client, :logger, :shadow_traffic_delivery_percent, :async_shadow_traffic,
|
23
|
-
:send_shadow_traffic_for_control
|
24
|
+
:send_shadow_traffic_for_control, :max_request_insertions
|
24
25
|
|
25
26
|
attr_accessor :request_logging_on, :enabled
|
26
27
|
|
@@ -30,14 +31,6 @@ module Promoted
|
|
30
31
|
@enabled
|
31
32
|
end
|
32
33
|
|
33
|
-
##
|
34
|
-
# A common compact properties method implementation.
|
35
|
-
def self.remove_all_properties
|
36
|
-
Proc.new do |properties|
|
37
|
-
nil
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
34
|
##
|
42
35
|
# Create and configure a new Promoted client.
|
43
36
|
def initialize(params={})
|
@@ -85,6 +78,8 @@ module Promoted
|
|
85
78
|
@send_shadow_traffic_for_control = params[:send_shadow_traffic_for_control] || false
|
86
79
|
end
|
87
80
|
|
81
|
+
@max_request_insertions = params[:max_request_insertions] || DEFAULT_MAX_REQUEST_INSERTIONS
|
82
|
+
|
88
83
|
@pool = nil
|
89
84
|
if @async_shadow_traffic
|
90
85
|
# Thread pool to process delivery of shadow traffic. Will silently drop excess requests beyond the queue
|
@@ -124,7 +119,7 @@ module Promoted
|
|
124
119
|
# Respect the enabled state
|
125
120
|
if !@enabled
|
126
121
|
return {
|
127
|
-
insertion: @pager.apply_paging(args[:
|
122
|
+
insertion: @pager.apply_paging(args[:request][:insertion], Promoted::Ruby::Client::INSERTION_PAGING_TYPE['UNPAGED'], args[:request][:paging])
|
128
123
|
# No log request returned when disabled
|
129
124
|
}
|
130
125
|
end
|
@@ -132,14 +127,22 @@ module Promoted
|
|
132
127
|
delivery_request_builder = RequestBuilder.new
|
133
128
|
delivery_request_builder.set_request_params(args)
|
134
129
|
|
130
|
+
only_log = delivery_request_builder.only_log != nil ? delivery_request_builder.only_log : @default_only_log
|
131
|
+
|
132
|
+
# Gets modified depending on the call.
|
133
|
+
should_send_shadow_traffic = @shadow_traffic_delivery_percent > 0
|
135
134
|
# perform_checks raises errors.
|
136
135
|
if @perform_checks
|
137
136
|
perform_common_checks!(args)
|
137
|
+
if !only_log && args[:insertion_page_type] == Promoted::Ruby::Client::INSERTION_PAGING_TYPE['PRE_PAGED'] then
|
138
|
+
err = DeliveryInsertionPageType.new
|
139
|
+
@logger.error(err) if @logger
|
140
|
+
raise err
|
141
|
+
end
|
138
142
|
|
139
|
-
if args[:insertion_page_type]
|
140
|
-
|
141
|
-
@logger.error(
|
142
|
-
raise err
|
143
|
+
if should_send_shadow_traffic && args[:insertion_page_type] != Promoted::Ruby::Client::INSERTION_PAGING_TYPE['UNPAGED'] then
|
144
|
+
should_send_shadow_traffic = false
|
145
|
+
@logger.error(ShadowTrafficInsertionPageType.new) if @logger
|
143
146
|
end
|
144
147
|
end
|
145
148
|
|
@@ -149,11 +152,16 @@ module Promoted
|
|
149
152
|
cohort_membership_to_log = nil
|
150
153
|
insertions_from_delivery = false
|
151
154
|
|
152
|
-
only_log = delivery_request_builder.only_log != nil ? delivery_request_builder.only_log : @default_only_log
|
153
155
|
deliver_err = false
|
154
156
|
|
157
|
+
# Trim any request insertions over the maximum allowed.
|
158
|
+
if delivery_request_builder.insertion.length > @max_request_insertions then
|
159
|
+
@logger.warn("Exceeded max request insertions, trimming") if @logger
|
160
|
+
delivery_request_builder.insertion = delivery_request_builder.insertion[0, @max_request_insertions]
|
161
|
+
end
|
162
|
+
|
155
163
|
begin
|
156
|
-
@pager.validate_paging(delivery_request_builder.
|
164
|
+
@pager.validate_paging(delivery_request_builder.insertion, delivery_request_builder.request[:paging])
|
157
165
|
rescue InvalidPagingError => err
|
158
166
|
# Invalid input, log and do SDK-side delivery.
|
159
167
|
@logger.warn(err) if @logger
|
@@ -177,16 +185,22 @@ module Promoted
|
|
177
185
|
deliver_err = true
|
178
186
|
@logger.error("Error calling delivery: " + err.message) if @logger
|
179
187
|
end
|
180
|
-
|
181
|
-
|
182
|
-
|
188
|
+
should_send_shadow_traffic = false
|
189
|
+
else
|
190
|
+
should_send_shadow_traffic &&= @send_shadow_traffic_for_control
|
183
191
|
end
|
184
192
|
|
185
193
|
insertions_from_delivery = (response != nil && !deliver_err);
|
186
194
|
response_insertions = delivery_request_builder.fill_details_from_response(
|
187
195
|
response && response[:insertion] || [])
|
188
196
|
end
|
189
|
-
|
197
|
+
|
198
|
+
should_send_shadow_traffic &&= should_send_as_shadow_traffic?
|
199
|
+
if should_send_shadow_traffic then
|
200
|
+
# Call Delivery API to send shadow traffic. This will create the request params with traffic type set.
|
201
|
+
deliver_shadow_traffic args, headers
|
202
|
+
end
|
203
|
+
|
190
204
|
request_to_log = nil
|
191
205
|
if !insertions_from_delivery then
|
192
206
|
request_to_log = delivery_request_builder.request
|
@@ -194,11 +208,13 @@ module Promoted
|
|
194
208
|
end
|
195
209
|
|
196
210
|
log_req = nil
|
211
|
+
exec_server = (insertions_from_delivery ? Promoted::Ruby::Client::EXECUTION_SERVER['API'] : Promoted::Ruby::Client::EXECUTION_SERVER['SDK'])
|
212
|
+
|
197
213
|
# We only return a log request if there's a request or cohort to log.
|
198
214
|
if request_to_log || cohort_membership_to_log
|
199
215
|
log_request_builder = RequestBuilder.new
|
200
216
|
log_request = {
|
201
|
-
:
|
217
|
+
:insertion => response_insertions,
|
202
218
|
:experiment => cohort_membership_to_log,
|
203
219
|
:request => request_to_log
|
204
220
|
}
|
@@ -212,55 +228,19 @@ module Promoted
|
|
212
228
|
# On a successful delivery request, we don't log the insertions
|
213
229
|
# or the request since they are logged on the server-side.
|
214
230
|
log_req = log_request_builder.log_request_params(
|
215
|
-
|
216
|
-
|
231
|
+
include_delivery_log: !insertions_from_delivery,
|
232
|
+
exec_server: exec_server)
|
217
233
|
end
|
218
234
|
|
219
235
|
client_response = {
|
220
236
|
insertion: response_insertions,
|
221
237
|
log_request: log_req,
|
222
|
-
execution_server:
|
238
|
+
execution_server: exec_server,
|
223
239
|
client_request_id: delivery_request_builder.client_request_id
|
224
240
|
}
|
225
241
|
return client_response
|
226
242
|
end
|
227
243
|
|
228
|
-
##
|
229
|
-
# Generate a log request for a subsequent call to send_log_request
|
230
|
-
# or for logging via alternative means.
|
231
|
-
def prepare_for_logging args, headers={}
|
232
|
-
args = Promoted::Ruby::Client::Util.translate_hash(args)
|
233
|
-
|
234
|
-
if !@enabled
|
235
|
-
return {
|
236
|
-
insertion: args[:full_insertion]
|
237
|
-
}
|
238
|
-
end
|
239
|
-
|
240
|
-
log_request_builder = RequestBuilder.new
|
241
|
-
|
242
|
-
# Note: This method expects as JSON (string keys) but internally, RequestBuilder
|
243
|
-
# transforms and works with symbol keys.
|
244
|
-
log_request_builder.set_request_params(args)
|
245
|
-
shadow_traffic_err = false
|
246
|
-
if @perform_checks
|
247
|
-
perform_common_checks! args
|
248
|
-
|
249
|
-
if @shadow_traffic_delivery_percent > 0 && args[:insertion_page_type] != Promoted::Ruby::Client::INSERTION_PAGING_TYPE['UNPAGED'] then
|
250
|
-
shadow_traffic_err = true
|
251
|
-
@logger.error(ShadowTrafficInsertionPageType.new) if @logger
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
log_request_builder.ensure_client_timestamp
|
256
|
-
|
257
|
-
if !shadow_traffic_err && should_send_as_shadow_traffic?
|
258
|
-
deliver_shadow_traffic args, headers
|
259
|
-
end
|
260
|
-
|
261
|
-
log_request_builder.log_request_params
|
262
|
-
end
|
263
|
-
|
264
244
|
##
|
265
245
|
# Sends a log request (previously created by a call to prepare_for_logging) to the metrics endpoint.
|
266
246
|
def send_log_request log_request_params, headers={}
|
@@ -277,7 +257,7 @@ module Promoted
|
|
277
257
|
##
|
278
258
|
# Creates response insertions for SDK-side delivery, when we don't get response insertions from Delivery API.
|
279
259
|
def build_sdk_response_insertions delivery_request_builder
|
280
|
-
response_insertions = @pager.apply_paging(delivery_request_builder.
|
260
|
+
response_insertions = @pager.apply_paging(delivery_request_builder.insertion, Promoted::Ruby::Client::INSERTION_PAGING_TYPE['UNPAGED'], delivery_request_builder.request[:paging])
|
281
261
|
delivery_request_builder.add_missing_insertion_ids! response_insertions
|
282
262
|
return response_insertions
|
283
263
|
end
|
@@ -354,7 +334,7 @@ module Promoted
|
|
354
334
|
delivery_request_params[:client_info][:traffic_type] = Promoted::Ruby::Client::TRAFFIC_TYPE['SHADOW']
|
355
335
|
|
356
336
|
begin
|
357
|
-
@pager.validate_paging(delivery_request_builder.
|
337
|
+
@pager.validate_paging(delivery_request_builder.insertion, delivery_request_builder.request[:paging])
|
358
338
|
rescue InvalidPagingError => err
|
359
339
|
# Invalid input, log and skip.
|
360
340
|
@logger.warn("Shadow traffic call failed with invalid paging #{err}") if @logger
|
@@ -382,6 +362,7 @@ module Promoted
|
|
382
362
|
begin
|
383
363
|
@validator.check_that_log_ids_not_set!(req)
|
384
364
|
@validator.validate_metrics_request!(req)
|
365
|
+
@validator.check_that_content_ids_are_set!(req)
|
385
366
|
rescue StandardError => err
|
386
367
|
@logger.error(err) if @logger
|
387
368
|
raise
|
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.homepage = 'https://github.com/promotedai/promoted-ruby-client'
|
15
15
|
spec.license = 'MIT'
|
16
16
|
|
17
|
-
spec.metadata["allowed_push_host"] = "
|
17
|
+
# spec.metadata["allowed_push_host"] = "http://rubygems.org/gems/promoted-ruby-client"
|
18
18
|
spec.metadata["homepage_uri"] = spec.homepage
|
19
19
|
spec.metadata["source_code_uri"] = "https://github.com/promotedai/promoted-ruby-client"
|
20
20
|
spec.metadata["changelog_uri"] = "https://github.com/promotedai/promoted-ruby-client/blob/master/CHANGELOG.md"
|
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.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- scottmcmaster
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-01-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -150,7 +150,6 @@ homepage: https://github.com/promotedai/promoted-ruby-client
|
|
150
150
|
licenses:
|
151
151
|
- MIT
|
152
152
|
metadata:
|
153
|
-
allowed_push_host: https://rubygems.org/
|
154
153
|
homepage_uri: https://github.com/promotedai/promoted-ruby-client
|
155
154
|
source_code_uri: https://github.com/promotedai/promoted-ruby-client
|
156
155
|
changelog_uri: https://github.com/promotedai/promoted-ruby-client/blob/master/CHANGELOG.md
|