vwo-sdk 1.30.0 → 1.35.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/lib/vwo/constants.rb +2 -1
- data/lib/vwo/core/bucketer.rb +42 -32
- data/lib/vwo/core/variation_decider.rb +309 -306
- data/lib/vwo/enums.rb +0 -134
- data/lib/vwo/logger.rb +7 -3
- data/lib/vwo/schemas/settings_file.rb +1 -0
- data/lib/vwo/services/batch_events_dispatcher.rb +43 -34
- data/lib/vwo/services/batch_events_queue.rb +33 -33
- data/lib/vwo/services/event_dispatcher.rb +39 -19
- data/lib/vwo/services/segment_evaluator.rb +11 -10
- data/lib/vwo/services/settings_file_processor.rb +7 -4
- data/lib/vwo/utils/campaign.rb +26 -27
- data/lib/vwo/utils/custom_dimensions.rb +14 -14
- data/lib/vwo/utils/feature.rb +6 -9
- data/lib/vwo/utils/impression.rb +65 -56
- data/lib/vwo/utils/log_message.rb +76 -0
- data/lib/vwo/utils/utility.rb +7 -0
- data/lib/vwo/utils/uuid.rb +12 -10
- data/lib/vwo/utils/validations.rb +56 -48
- data/lib/vwo.rb +437 -438
- metadata +5 -4
@@ -12,11 +12,11 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
require_relative '../logger'
|
16
15
|
require_relative '../enums'
|
17
16
|
require_relative '../utils/campaign'
|
18
17
|
require_relative '../services/segment_evaluator'
|
19
18
|
require_relative '../utils/validations'
|
19
|
+
require_relative '../utils/log_message'
|
20
20
|
require_relative 'bucketer'
|
21
21
|
require_relative '../constants'
|
22
22
|
require_relative '../services/hooks_manager'
|
@@ -40,7 +40,7 @@ class VWO
|
|
40
40
|
# @param[Class] - Class instance having the capability of
|
41
41
|
# get and save.
|
42
42
|
def initialize(settings_file, user_storage_service = nil, options = {})
|
43
|
-
@logger = VWO::Logger
|
43
|
+
@logger = VWO::Utils::Logger
|
44
44
|
@user_storage_service = user_storage_service
|
45
45
|
@bucketer = VWO::Core::Bucketer.new
|
46
46
|
@settings_file = settings_file
|
@@ -110,78 +110,84 @@ class VWO
|
|
110
110
|
variation = get_variation_if_whitelisting_passed(user_id, campaign, variation_targeting_variables, api_name, decision, true)
|
111
111
|
return variation if variation && variation['name']
|
112
112
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
113
|
+
if campaign.has_key?("isAlwaysCheckSegment")
|
114
|
+
is_presegmentation = check_presegmentation(campaign, user_id, custom_variables, api_name)
|
115
|
+
return get_variationIfPreSegmentation_applied(is_presegmentation, campaign, user_id, goal_identifier, decision)
|
116
|
+
else
|
117
|
+
user_campaign_map = get_user_storage(user_id, campaign_key)
|
118
|
+
variation = get_stored_variation(user_id, campaign_key, user_campaign_map) if valid_hash?(user_campaign_map)
|
119
119
|
|
120
|
-
|
121
|
-
|
122
|
-
variation['goal_identifier'] = user_campaign_map['goal_identifier']
|
120
|
+
if variation
|
121
|
+
variation = variation.dup # deep copy
|
123
122
|
end
|
124
|
-
|
125
|
-
@logger.log(
|
126
|
-
LogLevelEnum::INFO,
|
127
|
-
format(
|
128
|
-
LogMessageEnum::InfoMessages::GOT_STORED_VARIATION,
|
129
|
-
file: FILE,
|
130
|
-
campaign_key: campaign_key,
|
131
|
-
user_id: user_id,
|
132
|
-
variation_name: variation['name']
|
133
|
-
)
|
134
|
-
)
|
135
|
-
decision[:from_user_storage_service] = !!variation['name']
|
123
|
+
|
136
124
|
if variation
|
137
|
-
if
|
138
|
-
|
139
|
-
decision[:variation_id] = variation['id']
|
140
|
-
if campaign['type'] == CampaignTypes::FEATURE_TEST
|
141
|
-
decision[:is_feature_enabled] = variation['isFeatureEnabled']
|
142
|
-
end
|
125
|
+
if valid_string?(user_campaign_map['goal_identifier']) && api_name == ApiMethods::TRACK
|
126
|
+
variation['goal_identifier'] = user_campaign_map['goal_identifier']
|
143
127
|
end
|
144
|
-
@
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
user_id: user_id
|
128
|
+
@has_stored_variation = true
|
129
|
+
@logger.log(
|
130
|
+
LogLevelEnum::INFO,
|
131
|
+
'GOT_STORED_VARIATION',
|
132
|
+
{
|
133
|
+
'{file}' => FILE,
|
134
|
+
'{campaignKey}' => campaign_key,
|
135
|
+
'{userId}' => user_id,
|
136
|
+
'{variationName}' => variation['name']
|
137
|
+
}
|
155
138
|
)
|
156
|
-
|
157
|
-
|
158
|
-
|
139
|
+
decision[:from_user_storage_service] = !!variation['name']
|
140
|
+
if variation
|
141
|
+
if campaign['type'] == CampaignTypes::VISUAL_AB || campaign['type'] == CampaignTypes::FEATURE_TEST
|
142
|
+
decision[:variation_name] = variation['name']
|
143
|
+
decision[:variation_id] = variation['id']
|
144
|
+
if campaign['type'] == CampaignTypes::FEATURE_TEST
|
145
|
+
decision[:is_feature_enabled] = variation['isFeatureEnabled']
|
146
|
+
end
|
147
|
+
end
|
148
|
+
@hooks_manager.execute(decision)
|
149
|
+
end
|
150
|
+
return variation
|
151
|
+
else
|
159
152
|
@logger.log(
|
160
153
|
LogLevelEnum::DEBUG,
|
161
|
-
|
162
|
-
|
163
|
-
file
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
)
|
154
|
+
'USER_STORAGE_SERVICE_NO_STORED_DATA',
|
155
|
+
{
|
156
|
+
'{file}' => FILE,
|
157
|
+
'{campaignKey}' => campaign_key,
|
158
|
+
'{userId}' => user_id
|
159
|
+
}
|
168
160
|
)
|
169
|
-
|
170
|
-
@
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
161
|
+
|
162
|
+
if ([ApiMethods::TRACK, ApiMethods::GET_VARIATION_NAME, ApiMethods::GET_FEATURE_VARIABLE_VALUE].include? api_name) && @user_storage_service
|
163
|
+
@logger.log(
|
164
|
+
LogLevelEnum::WARNING,
|
165
|
+
'CAMPAIGN_NOT_ACTIVATED',
|
166
|
+
{
|
167
|
+
'{file}' => FILE,
|
168
|
+
'{campaignKey}' => campaign_key,
|
169
|
+
'{userId}' => user_id,
|
170
|
+
'{api}' => api_name
|
171
|
+
}
|
179
172
|
)
|
180
|
-
|
181
|
-
|
173
|
+
|
174
|
+
@logger.log(
|
175
|
+
LogLevelEnum::INFO,
|
176
|
+
'CAMPAIGN_NOT_ACTIVATED',
|
177
|
+
{
|
178
|
+
'{file}' => FILE,
|
179
|
+
'{campaignKey}' => campaign_key,
|
180
|
+
'{userId}' => user_id,
|
181
|
+
'{reason}' => api_name == ApiMethods::TRACK ? 'track it' : 'get the decision/value'
|
182
|
+
}
|
183
|
+
)
|
184
|
+
return
|
185
|
+
end
|
182
186
|
end
|
183
187
|
end
|
184
188
|
|
189
|
+
|
190
|
+
|
185
191
|
# Pre-segmentation
|
186
192
|
is_presegmentation = check_presegmentation(campaign, user_id, custom_variables, api_name)
|
187
193
|
is_presegmentation_and_traffic_passed = is_presegmentation && @bucketer.user_part_of_campaign?(user_id, campaign)
|
@@ -191,61 +197,57 @@ class VWO
|
|
191
197
|
|
192
198
|
if is_presegmentation_and_traffic_passed && is_campaign_part_of_group
|
193
199
|
group_campaigns = get_group_campaigns(@settings_file, group_id)
|
194
|
-
|
195
200
|
if group_campaigns
|
196
201
|
is_any_campaign_whitelisted_or_stored = check_whitelisting_or_storage_for_grouped_campaigns(user_id, campaign, group_campaigns, group_name, variation_targeting_variables, true)
|
197
|
-
|
198
202
|
if is_any_campaign_whitelisted_or_stored
|
199
203
|
@logger.log(
|
200
204
|
LogLevelEnum::INFO,
|
201
|
-
|
202
|
-
|
203
|
-
file
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
205
|
+
'MEG_CALLED_CAMPAIGN_NOT_WINNER',
|
206
|
+
{
|
207
|
+
'{file}' => FILE,
|
208
|
+
'{campaignKey}' => campaign_key,
|
209
|
+
'{userId}' => user_id,
|
210
|
+
'{groupName}' => group_name,
|
211
|
+
}
|
208
212
|
)
|
209
213
|
return nil
|
210
214
|
end
|
211
|
-
|
212
215
|
eligible_campaigns = get_eligible_campaigns(user_id, group_campaigns, campaign, custom_variables)
|
213
216
|
non_eligible_campaigns_key = get_non_eligible_campaigns_key(eligible_campaigns, group_campaigns)
|
214
|
-
|
215
217
|
@logger.log(
|
216
218
|
LogLevelEnum::DEBUG,
|
217
|
-
|
218
|
-
|
219
|
-
file
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
219
|
+
'MEG_ELIGIBLE_CAMPAIGNS',
|
220
|
+
{
|
221
|
+
'{file}' => FILE,
|
222
|
+
'{userId}' => user_id,
|
223
|
+
'{eligibleCampaignKeys}' => get_eligible_campaigns_key(eligible_campaigns).join(","),
|
224
|
+
'{inEligibleText}' => non_eligible_campaigns_key ? ("campaigns:" + non_eligible_campaigns_key.join("'")) : "no campaigns",
|
225
|
+
'{groupName}' => group_name
|
226
|
+
}
|
225
227
|
)
|
226
228
|
|
227
229
|
@logger.log(
|
228
230
|
LogLevelEnum::INFO,
|
229
|
-
|
230
|
-
|
231
|
-
file
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
231
|
+
'MEG_ELIGIBLE_CAMPAIGNS',
|
232
|
+
{
|
233
|
+
'{file}' => FILE,
|
234
|
+
'{userId}' => user_id,
|
235
|
+
'{noOfEligibleCampaigns}' => eligible_campaigns.length,
|
236
|
+
'{noOfGroupCampaigns}' => group_campaigns.length,
|
237
|
+
'{groupName}' => group_name
|
238
|
+
}
|
237
239
|
)
|
238
240
|
|
239
241
|
winner_campaign = get_winner_campaign(user_id, eligible_campaigns, group_id)
|
240
242
|
@logger.log(
|
241
243
|
LogLevelEnum::INFO,
|
242
|
-
|
243
|
-
|
244
|
-
file
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
244
|
+
'MEG_GOT_WINNER_CAMPAIGN',
|
245
|
+
{
|
246
|
+
'{file}' => FILE,
|
247
|
+
'{userId}' => user_id,
|
248
|
+
'{campaignKey}' => winner_campaign["key"],
|
249
|
+
'{groupName}' => group_name,
|
250
|
+
}
|
249
251
|
)
|
250
252
|
|
251
253
|
if winner_campaign && winner_campaign["id"] == campaign["id"]
|
@@ -258,31 +260,61 @@ class VWO
|
|
258
260
|
else
|
259
261
|
@logger.log(
|
260
262
|
LogLevelEnum::INFO,
|
261
|
-
|
262
|
-
|
263
|
-
file
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
263
|
+
'MEG_CALLED_CAMPAIGN_NOT_WINNER',
|
264
|
+
{
|
265
|
+
'{file}' => FILE,
|
266
|
+
'{campaignKey}' => campaign_key,
|
267
|
+
'{userId}' => user_id,
|
268
|
+
'{groupName}' => group_name,
|
269
|
+
}
|
268
270
|
)
|
269
271
|
return nil
|
270
272
|
end
|
271
273
|
end
|
272
274
|
end
|
273
275
|
|
274
|
-
if variation
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
LogLevelEnum::INFO,
|
282
|
-
format(LogMessageEnum::InfoMessages::NO_VARIATION_ALLOCATED, file: FILE, campaign_key: campaign_key, user_id: user_id)
|
283
|
-
)
|
276
|
+
if variation
|
277
|
+
if campaign['type'] == CampaignTypes::VISUAL_AB || campaign['type'] == CampaignTypes::FEATURE_TEST
|
278
|
+
decision[:variation_name] = variation['name']
|
279
|
+
decision[:variation_id] = variation['id']
|
280
|
+
if campaign['type'] == CampaignTypes::FEATURE_TEST
|
281
|
+
decision[:is_feature_enabled] = variation['isFeatureEnabled']
|
282
|
+
end
|
284
283
|
end
|
284
|
+
@hooks_manager.execute(decision)
|
285
|
+
return variation
|
286
|
+
end
|
287
|
+
|
288
|
+
return get_variationIfPreSegmentation_applied(is_presegmentation, campaign, user_id, goal_identifier, decision)
|
289
|
+
end
|
285
290
|
|
291
|
+
# Get variation by murmur logic if pre segmentation pass
|
292
|
+
#
|
293
|
+
# @param[Boolean] :is_presegmentation The unique key assigned to User
|
294
|
+
# @param[Hash] :campaign Campaign hash for Unique campaign key
|
295
|
+
# @param[String] :user_id the unique ID assigned to User
|
296
|
+
# @param[String] :goal_identifier goal Identifier used in track API
|
297
|
+
# @param[Hash] :decision data containing campaign info passed to hooks manager
|
298
|
+
#
|
299
|
+
# @return[Hash]
|
300
|
+
def get_variationIfPreSegmentation_applied(is_presegmentation, campaign, user_id, goal_identifier, decision)
|
301
|
+
unless is_presegmentation
|
302
|
+
return nil
|
303
|
+
end
|
304
|
+
campaign_key = campaign['key']
|
305
|
+
variation = get_variation_allotted(user_id, campaign)
|
306
|
+
if variation && variation['name']
|
307
|
+
save_user_storage(user_id, campaign_key, campaign['type'], variation['name'], goal_identifier) if variation['name']
|
308
|
+
else
|
309
|
+
@logger.log(
|
310
|
+
LogLevelEnum::INFO,
|
311
|
+
'DECISION_NO_VARIATION_ALLOTED',
|
312
|
+
{
|
313
|
+
'{file}' => FILE,
|
314
|
+
'{campaignKey}' => campaign_key,
|
315
|
+
'{userId}' => user_id
|
316
|
+
}
|
317
|
+
)
|
286
318
|
end
|
287
319
|
|
288
320
|
if variation
|
@@ -309,37 +341,29 @@ class VWO
|
|
309
341
|
unless valid_value?(user_id)
|
310
342
|
@logger.log(
|
311
343
|
LogLevelEnum::ERROR,
|
312
|
-
|
344
|
+
'USER_ID_INVALID',
|
345
|
+
{
|
346
|
+
'{file}' => FILE,
|
347
|
+
'{userId}' => user_id
|
348
|
+
},
|
349
|
+
disable_logs
|
313
350
|
)
|
314
351
|
return
|
315
352
|
end
|
316
353
|
|
317
|
-
if @bucketer.user_part_of_campaign?(user_id, campaign)
|
318
|
-
variation = get_variation_of_campaign_for_user(user_id, campaign)
|
319
|
-
@logger.log(
|
320
|
-
LogLevelEnum::DEBUG,
|
321
|
-
format(
|
322
|
-
LogMessageEnum::DebugMessages::GOT_VARIATION_FOR_USER,
|
323
|
-
file: FILE,
|
324
|
-
variation_name: variation['name'],
|
325
|
-
user_id: user_id,
|
326
|
-
campaign_key: campaign['key'],
|
327
|
-
method: 'get_variation_allotted'
|
328
|
-
),
|
329
|
-
disable_logs
|
330
|
-
)
|
354
|
+
if @bucketer.user_part_of_campaign?(user_id, campaign, true)
|
355
|
+
variation = get_variation_of_campaign_for_user(user_id, campaign, disable_logs)
|
331
356
|
variation
|
332
357
|
else
|
333
358
|
# not part of campaign
|
334
359
|
@logger.log(
|
335
|
-
LogLevelEnum::
|
336
|
-
|
337
|
-
|
338
|
-
file
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
),
|
360
|
+
LogLevelEnum::INFO,
|
361
|
+
'USER_NOT_PART_OF_CAMPAIGN',
|
362
|
+
{
|
363
|
+
'{file}' => FILE,
|
364
|
+
'{campaignKey}' => nil,
|
365
|
+
'{userId}' => user_id
|
366
|
+
},
|
343
367
|
disable_logs
|
344
368
|
)
|
345
369
|
nil
|
@@ -352,44 +376,36 @@ class VWO
|
|
352
376
|
# @param[Hash] :campaign The Campaign of which user is to be made a part of
|
353
377
|
# @return[Hash] Variation allotted to User
|
354
378
|
|
355
|
-
def get_variation_of_campaign_for_user(user_id, campaign)
|
356
|
-
|
357
|
-
@logger.log(
|
358
|
-
LogLevelEnum::ERROR,
|
359
|
-
format(
|
360
|
-
LogMessageEnum::ErrorMessages::INVALID_CAMPAIGN,
|
361
|
-
file: FILE,
|
362
|
-
method: 'get_variation_of_campaign_for_user'
|
363
|
-
)
|
364
|
-
)
|
365
|
-
return nil
|
366
|
-
end
|
367
|
-
|
368
|
-
variation = @bucketer.bucket_user_to_variation(user_id, campaign)
|
379
|
+
def get_variation_of_campaign_for_user(user_id, campaign, disable_logs = false)
|
380
|
+
variation = @bucketer.bucket_user_to_variation(user_id, campaign, disable_logs)
|
369
381
|
|
370
382
|
if variation && variation['name']
|
371
383
|
@logger.log(
|
372
384
|
LogLevelEnum::INFO,
|
373
|
-
|
374
|
-
|
375
|
-
file
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
385
|
+
'USER_VARIATION_ALLOCATION_STATUS',
|
386
|
+
{
|
387
|
+
'{file}' => FILE,
|
388
|
+
'{status}' => variation ? 'got variation:' + variation['name'] : 'did not get any variation',
|
389
|
+
'{userId}' => user_id,
|
390
|
+
'{campaignKey}' => campaign['key']
|
391
|
+
},
|
392
|
+
disable_logs
|
380
393
|
)
|
381
394
|
return variation
|
382
395
|
end
|
383
396
|
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
397
|
+
if campaign
|
398
|
+
@logger.log(
|
399
|
+
LogLevelEnum::INFO,
|
400
|
+
'DECISION_NO_VARIATION_ALLOTED',
|
401
|
+
{
|
402
|
+
'{file}' => FILE,
|
403
|
+
'{userId}' => user_id,
|
404
|
+
'{campaignKey}' => campaign['key']
|
405
|
+
},
|
406
|
+
disable_logs
|
391
407
|
)
|
392
|
-
|
408
|
+
end
|
393
409
|
nil
|
394
410
|
end
|
395
411
|
|
@@ -406,7 +422,8 @@ class VWO
|
|
406
422
|
unless @user_storage_service
|
407
423
|
@logger.log(
|
408
424
|
LogLevelEnum::DEBUG,
|
409
|
-
|
425
|
+
'USER_STORAGE_SERVICE_NOT_CONFIGURED',
|
426
|
+
{'{file}' => FILE},
|
410
427
|
disable_logs
|
411
428
|
)
|
412
429
|
return false
|
@@ -423,27 +440,24 @@ class VWO
|
|
423
440
|
|
424
441
|
@logger.log(
|
425
442
|
LogLevelEnum::INFO,
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
format(
|
433
|
-
LogMessageEnum::InfoMessages::VARIATION_ALLOCATED,
|
434
|
-
file: FILE,
|
435
|
-
campaign_key: campaign_key,
|
436
|
-
user_id: user_id,
|
437
|
-
variation_name: variation_name,
|
438
|
-
campaign_type: campaign_type
|
439
|
-
),
|
443
|
+
'SETTING_DATA_USER_STORAGE_SERVICE',
|
444
|
+
{
|
445
|
+
'{file}' => FILE,
|
446
|
+
'{userId}' => user_id,
|
447
|
+
'{campaignKey}' => campaign_key
|
448
|
+
},
|
440
449
|
disable_logs
|
441
450
|
)
|
442
451
|
true
|
443
|
-
rescue StandardError
|
452
|
+
rescue StandardError => e
|
444
453
|
@logger.log(
|
445
454
|
LogLevelEnum::ERROR,
|
446
|
-
|
455
|
+
'USER_STORAGE_SERVICE_SET_FAILED',
|
456
|
+
{
|
457
|
+
'{file}' => FILE,
|
458
|
+
'{userId}' => user_id,
|
459
|
+
'{error}' => e.message
|
460
|
+
},
|
447
461
|
disable_logs
|
448
462
|
)
|
449
463
|
false
|
@@ -464,7 +478,7 @@ class VWO
|
|
464
478
|
|
465
479
|
def evaluate_whitelisting(user_id, campaign, api_name, campaign_key, variation_targeting_variables = {}, disable_logs = false)
|
466
480
|
if campaign.key?('isUserListEnabled') && campaign["isUserListEnabled"]
|
467
|
-
vwo_user_id = generator_for(user_id, @settings_file['accountId'])
|
481
|
+
vwo_user_id = generator_for(user_id, @settings_file['accountId'], true)
|
468
482
|
if variation_targeting_variables.nil?
|
469
483
|
variation_targeting_variables = { _vwo_user_id: vwo_user_id }
|
470
484
|
else
|
@@ -490,36 +504,33 @@ class VWO
|
|
490
504
|
status = StatusEnum::FAILED
|
491
505
|
end
|
492
506
|
@logger.log(
|
493
|
-
LogLevelEnum::
|
494
|
-
|
495
|
-
|
496
|
-
file
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
),
|
507
|
+
LogLevelEnum::INFO,
|
508
|
+
'SEGMENTATION_STATUS',
|
509
|
+
{
|
510
|
+
'{file}' => FILE,
|
511
|
+
'{campaignKey}' => campaign_key,
|
512
|
+
'{userId}' => user_id,
|
513
|
+
'{customVariables}' => variation_targeting_variables,
|
514
|
+
'{status}' => status,
|
515
|
+
'{segmentationType}' => SegmentationTypeEnum::WHITELISTING,
|
516
|
+
'{variation}' => status == StatusEnum::PASSED ? (campaign['type'] == CampaignTypes::FEATURE_ROLLOUT ? 'and hence becomes part of the rollout' : variation['name'] + ' and hence becomes part of the rollout') : '',
|
517
|
+
},
|
505
518
|
disable_logs
|
506
519
|
)
|
507
520
|
else
|
508
521
|
@logger.log(
|
509
522
|
LogLevelEnum::DEBUG,
|
510
|
-
|
511
|
-
|
512
|
-
file
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
),
|
523
|
+
'SEGMENTATION_SKIPPED',
|
524
|
+
{
|
525
|
+
'{file}' => FILE,
|
526
|
+
'{campaignKey}' => campaign_key,
|
527
|
+
'{userId}' => user_id,
|
528
|
+
'{variation}' => campaign['type'] == CampaignTypes::FEATURE_ROLLOUT ? '' : 'for variation:' + variation['name']
|
529
|
+
},
|
518
530
|
disable_logs
|
519
531
|
)
|
520
532
|
end
|
521
533
|
end
|
522
|
-
|
523
534
|
if targeted_variations.length > 1
|
524
535
|
targeted_variations_deep_clone = Marshal.load(Marshal.dump(targeted_variations))
|
525
536
|
scale_variation_weights(targeted_variations_deep_clone)
|
@@ -541,7 +552,8 @@ class VWO
|
|
541
552
|
targeted_variations_deep_clone,
|
542
553
|
@bucketer.get_bucket_value_for_user(
|
543
554
|
user_id,
|
544
|
-
campaign
|
555
|
+
campaign,
|
556
|
+
disable_logs
|
545
557
|
)
|
546
558
|
)
|
547
559
|
else
|
@@ -587,28 +599,36 @@ class VWO
|
|
587
599
|
unless @user_storage_service
|
588
600
|
@logger.log(
|
589
601
|
LogLevelEnum::DEBUG,
|
590
|
-
|
602
|
+
'USER_STORAGE_SERVICE_NOT_CONFIGURED',
|
603
|
+
{'{file}' => FILE},
|
591
604
|
disable_logs
|
592
605
|
)
|
593
606
|
return false
|
594
607
|
end
|
595
608
|
|
596
609
|
data = @user_storage_service.get(user_id, campaign_key)
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
610
|
+
if data
|
611
|
+
@logger.log(
|
612
|
+
LogLevelEnum::INFO,
|
613
|
+
'GETTING_DATA_USER_STORAGE_SERVICE',
|
614
|
+
{
|
615
|
+
'{file}' => FILE,
|
616
|
+
'{userId}' => user_id,
|
617
|
+
'{campaignKey}' => campaign_key
|
618
|
+
},
|
619
|
+
disable_logs
|
620
|
+
)
|
621
|
+
end
|
607
622
|
data
|
608
|
-
rescue StandardError
|
623
|
+
rescue StandardError => e
|
609
624
|
@logger.log(
|
610
625
|
LogLevelEnum::ERROR,
|
611
|
-
|
626
|
+
'USER_STORAGE_SERVICE_GET_FAILED',
|
627
|
+
{
|
628
|
+
'{file}' => FILE,
|
629
|
+
'{userId}' => user_id,
|
630
|
+
'{error}' => e.message
|
631
|
+
},
|
612
632
|
disable_logs
|
613
633
|
)
|
614
634
|
false
|
@@ -627,17 +647,6 @@ class VWO
|
|
627
647
|
return unless user_campaign_map['campaign_key'] == campaign_key
|
628
648
|
|
629
649
|
variation_name = user_campaign_map['variation_name']
|
630
|
-
@logger.log(
|
631
|
-
LogLevelEnum::DEBUG,
|
632
|
-
format(
|
633
|
-
LogMessageEnum::DebugMessages::GETTING_STORED_VARIATION,
|
634
|
-
file: FILE,
|
635
|
-
campaign_key: campaign_key,
|
636
|
-
user_id: user_id,
|
637
|
-
variation_name: variation_name
|
638
|
-
),
|
639
|
-
disable_logs
|
640
|
-
)
|
641
650
|
|
642
651
|
get_campaign_variation(
|
643
652
|
@settings_file,
|
@@ -662,59 +671,53 @@ class VWO
|
|
662
671
|
|
663
672
|
if is_valid_segments
|
664
673
|
unless custom_variables
|
665
|
-
@logger.log(
|
666
|
-
LogLevelEnum::INFO,
|
667
|
-
format(
|
668
|
-
LogMessageEnum::InfoMessages::NO_CUSTOM_VARIABLES,
|
669
|
-
file: FILE,
|
670
|
-
campaign_key: campaign_key,
|
671
|
-
user_id: user_id,
|
672
|
-
api_name: api_name
|
673
|
-
),
|
674
|
-
disable_logs
|
675
|
-
)
|
676
674
|
custom_variables = {}
|
677
675
|
end
|
678
|
-
|
679
|
-
@logger.log(
|
680
|
-
LogLevelEnum::INFO,
|
681
|
-
format(
|
682
|
-
LogMessageEnum::InfoMessages::USER_FAILED_SEGMENTATION,
|
683
|
-
file: FileNameEnum::SegmentEvaluator,
|
684
|
-
user_id: user_id,
|
685
|
-
campaign_key: campaign_key,
|
686
|
-
custom_variables: custom_variables
|
687
|
-
),
|
688
|
-
disable_logs
|
689
|
-
)
|
690
|
-
return false
|
691
|
-
end
|
676
|
+
response = @segment_evaluator.evaluate(campaign_key, user_id, segments, custom_variables, disable_logs)
|
692
677
|
@logger.log(
|
693
678
|
LogLevelEnum::INFO,
|
694
|
-
|
695
|
-
|
696
|
-
file
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
679
|
+
'SEGMENTATION_STATUS',
|
680
|
+
{
|
681
|
+
'{file}' => FILE,
|
682
|
+
'{userId}' => user_id,
|
683
|
+
'{status}' => response ? 'passed' : 'failed',
|
684
|
+
'{campaignKey}' => campaign_key,
|
685
|
+
'{customVariables}' => custom_variables,
|
686
|
+
'{segmentationType}' => 'pre-segmentation',
|
687
|
+
'{variation}' => ''
|
688
|
+
},
|
701
689
|
disable_logs
|
702
690
|
)
|
691
|
+
return response
|
703
692
|
else
|
704
693
|
@logger.log(
|
705
|
-
LogLevelEnum::
|
706
|
-
|
707
|
-
|
708
|
-
file
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
),
|
694
|
+
LogLevelEnum::DEBUG,
|
695
|
+
'SEGMENTATION_SKIPPED',
|
696
|
+
{
|
697
|
+
'{file}' => FILE,
|
698
|
+
'{userId}' => user_id,
|
699
|
+
'{campaignKey}' => campaign_key,
|
700
|
+
'{variation}' => ''
|
701
|
+
},
|
714
702
|
disable_logs
|
715
703
|
)
|
716
704
|
end
|
717
705
|
true
|
706
|
+
rescue StandardError => e
|
707
|
+
@logger.log(
|
708
|
+
LogLevelEnum::ERROR,
|
709
|
+
'SEGMENTATION_ERROR',
|
710
|
+
{
|
711
|
+
'{file}' => FILE,
|
712
|
+
'{userId}' => user_id,
|
713
|
+
'{campaignKey}' => campaign_key,
|
714
|
+
'{variation}' => '',
|
715
|
+
'{customVariables}' => custom_variables,
|
716
|
+
'{err}' => e.message
|
717
|
+
},
|
718
|
+
disable_logs
|
719
|
+
)
|
720
|
+
false
|
718
721
|
end
|
719
722
|
|
720
723
|
# Finds and returns eligible campaigns from group_campaigns.
|
@@ -729,7 +732,7 @@ class VWO
|
|
729
732
|
eligible_campaigns = []
|
730
733
|
|
731
734
|
group_campaigns.each do |campaign|
|
732
|
-
if called_campaign["id"] == campaign["id"] || check_presegmentation(campaign, user_id, custom_variables, '', true) && @bucketer.user_part_of_campaign?(user_id, campaign)
|
735
|
+
if called_campaign["id"] == campaign["id"] || check_presegmentation(campaign, user_id, custom_variables, '', true) && @bucketer.user_part_of_campaign?(user_id, campaign, true)
|
733
736
|
eligible_campaigns.push(campaign)
|
734
737
|
end
|
735
738
|
end
|
@@ -806,14 +809,14 @@ class VWO
|
|
806
809
|
if targeted_variation
|
807
810
|
@logger.log(
|
808
811
|
LogLevelEnum::INFO,
|
809
|
-
|
810
|
-
|
811
|
-
file
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
type
|
816
|
-
|
812
|
+
'OTHER_CAMPAIGN_SATISFIES_WHITELISTING_STORAGE',
|
813
|
+
{
|
814
|
+
'{file}' => FILE,
|
815
|
+
'{campaignKey}' => campaign["key"],
|
816
|
+
'{userId}' => user_id,
|
817
|
+
'{groupName}' => group_name,
|
818
|
+
'{type}' => "whitelisting"
|
819
|
+
},
|
817
820
|
disable_logs
|
818
821
|
)
|
819
822
|
return true
|
@@ -827,14 +830,14 @@ class VWO
|
|
827
830
|
if user_storage_data
|
828
831
|
@logger.log(
|
829
832
|
LogLevelEnum::INFO,
|
830
|
-
|
831
|
-
|
832
|
-
file
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
type
|
837
|
-
|
833
|
+
'OTHER_CAMPAIGN_SATISFIES_WHITELISTING_STORAGE',
|
834
|
+
{
|
835
|
+
'{file}' => FILE,
|
836
|
+
'{campaignKey}' => campaign["key"],
|
837
|
+
'{userId}' => user_id,
|
838
|
+
'{groupName}' => group_name,
|
839
|
+
'{type}' => "user storag"
|
840
|
+
},
|
838
841
|
disable_logs
|
839
842
|
)
|
840
843
|
return true
|
@@ -872,17 +875,16 @@ class VWO
|
|
872
875
|
|
873
876
|
@logger.log(
|
874
877
|
LogLevelEnum::INFO,
|
875
|
-
|
876
|
-
|
877
|
-
file
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
),
|
878
|
+
'SEGMENTATION_STATUS',
|
879
|
+
{
|
880
|
+
'{file}' => FILE,
|
881
|
+
'{campaignKey}' => campaign_key,
|
882
|
+
'{userId}' => user_id,
|
883
|
+
'{customVariables}' => variation_targeting_variables ? variation_targeting_variables : {},
|
884
|
+
'{status}' => status,
|
885
|
+
'{segmentationType}' => SegmentationTypeEnum::WHITELISTING,
|
886
|
+
'{variation}' => (status == StatusEnum::PASSED && campaign['type'] != CampaignTypes::FEATURE_ROLLOUT) ? "for variation:#{variation['name']}" : ' '
|
887
|
+
},
|
886
888
|
disable_logs
|
887
889
|
)
|
888
890
|
|
@@ -901,14 +903,15 @@ class VWO
|
|
901
903
|
return variation if variation && variation['name']
|
902
904
|
else
|
903
905
|
@logger.log(
|
904
|
-
LogLevelEnum::
|
905
|
-
|
906
|
-
|
907
|
-
file
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
906
|
+
LogLevelEnum::DEBUG,
|
907
|
+
'WHITELISTING_SKIPPED',
|
908
|
+
{
|
909
|
+
'{file}' => FILE,
|
910
|
+
'{campaignKey}' => campaign_key,
|
911
|
+
'{userId}' => user_id,
|
912
|
+
'{reason}' => '',
|
913
|
+
'{variation}' => ''
|
914
|
+
},
|
912
915
|
disable_logs
|
913
916
|
)
|
914
917
|
end
|