vwo-sdk 1.29.0 → 1.35.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/vwo/constants.rb +2 -1
- data/lib/vwo/core/bucketer.rb +46 -36
- 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 +17 -2
@@ -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
|