/// <summary> /// Allocate variation by checking UserStorageService, Campaign Traffic Allocation and compute UserHash to check variation allocation by bucketing. /// </summary> /// <param name="campaignKey"></param> /// <param name="userId"></param> /// <param name="apiName"></param> /// <param name="campaign"></param> /// <param name="customVariables"></param> /// <param name="variationTargetingVariables"></param> /// <returns> /// If Variation is allocated, returns UserAssignedInfo with valid details, else return Empty UserAssignedInfo. /// </returns> private UserAllocationInfo AllocateVariation(string campaignKey, string userId, BucketedCampaign campaign, Dictionary <string, dynamic> customVariables, Dictionary <string, dynamic> variationTargetingVariables, string apiName = null) { Variation TargettedVariation = this.FindTargetedVariation(apiName, campaign, campaignKey, userId, customVariables, variationTargetingVariables); if (TargettedVariation != null) { return(new UserAllocationInfo(TargettedVariation, campaign)); } UserStorageMap userStorageMap = this._userStorageService.GetUserMap(campaignKey, userId); BucketedCampaign selectedCampaign = this._campaignAllocator.Allocate(this._settings, userStorageMap, campaignKey, userId, apiName); if (userStorageMap != null && userStorageMap.VariationName != null) { Variation variation = this._variationAllocator.GetSavedVariation(campaign, userStorageMap.VariationName.ToString()); return(new UserAllocationInfo(variation, selectedCampaign)); } if (selectedCampaign != null) { Variation variation = this._variationAllocator.Allocate(userStorageMap, selectedCampaign, userId); if (variation != null) { if (campaign.Segments.Count > 0) { string segmentationType = Constants.SegmentationType.PRE_SEGMENTATION; if (customVariables == null) { LogInfoMessage.NoCustomVariables(typeof(IVWOClient).FullName, userId, campaignKey, apiName); customVariables = new Dictionary <string, dynamic>(); } if (variationTargetingVariables == null) { variationTargetingVariables = new Dictionary <string, dynamic>(); } if (!this._segmentEvaluator.evaluate(userId, campaignKey, segmentationType, campaign.Segments, customVariables)) { return(new UserAllocationInfo()); } } else { LogInfoMessage.SkippingPreSegmentation(typeof(IVWOClient).FullName, userId, campaignKey, apiName); } LogInfoMessage.VariationAllocated(file, userId, campaignKey, variation.Name); LogDebugMessage.GotVariationForUser(file, userId, campaignKey, variation.Name, nameof(AllocateVariation)); this._userStorageService.SetUserMap(userId, selectedCampaign.Key, variation.Name); return(new UserAllocationInfo(variation, selectedCampaign)); } } LogInfoMessage.NoVariationAllocated(file, userId, campaignKey); return(new UserAllocationInfo()); }
/// <summary> /// Allocate Variation by checking previously assigned variation if userStorageMap is provided, else by computing User Hash and matching it in bucket for eligible variation. /// </summary> /// <param name="userStorageMap"></param> /// <param name="campaign"></param> /// <param name="userId"></param> /// <returns></returns> public Variation Allocate(UserStorageMap userStorageMap, BucketedCampaign campaign, string userId) { if (campaign == null) { return(null); } if (userStorageMap == null) { double maxVal = Constants.Variation.MAX_TRAFFIC_VALUE; double multiplier = maxVal / campaign.PercentTraffic / 100; ///This is to evenly spread all user among variations. var bucketValue = this._userHasher.ComputeBucketValue(userId, maxVal, multiplier, out double hashValue); var selectedVariation = campaign.Variations.Find(bucketValue); LogDebugMessage.VariationHashBucketValue(file, userId, campaign.Key, campaign.PercentTraffic, hashValue, bucketValue); return(selectedVariation); } return(campaign.Variations.Find(userStorageMap.VariationName, GetVariationName)); }
private Variation FindTargetedVariation(string apiName, BucketedCampaign campaign, string campaignKey, string userId, Dictionary <string, dynamic> customVariables, Dictionary <string, dynamic> variationTargetingVariables) { if (campaign.IsForcedVariationEnabled) { if (variationTargetingVariables == null) { variationTargetingVariables = new Dictionary <string, dynamic>(); variationTargetingVariables.Add("_vwoUserId", userId); } else { if (variationTargetingVariables.ContainsKey("_vwoUserId")) { variationTargetingVariables["_vwoUserId"] = userId; } else { variationTargetingVariables.Add("_vwoUserId", userId); } } List <Variation> whiteListedVariations = this.GetWhiteListedVariationsList(apiName, userId, campaign, campaignKey, customVariables, variationTargetingVariables); string status = Constants.WhitelistingStatus.FAILED; string variationString = " "; Variation variation = this._variationAllocator.TargettedVariation(userId, whiteListedVariations); if (variation != null) { status = Constants.WhitelistingStatus.PASSED; variationString = $"and variation: {variation.Name} is assigned"; } LogInfoMessage.WhitelistingStatus(typeof(IVWOClient).FullName, userId, campaignKey, apiName, variationString, status); return(variation); } LogInfoMessage.SkippingWhitelisting(typeof(IVWOClient).FullName, userId, campaignKey, apiName); return(null); }
/// <summary> /// If variation is assigned, allocate the goal using goalIdentifier. /// </summary> /// <param name="campaignKey"></param> /// <param name="userId"></param> /// <param name="goalIdentifier"></param> /// <param name="campaign"></param> /// <param name="customVariables"></param> /// <param name="variationTargetingVariables"></param> /// <param name="apiName"></param> /// <returns> /// If Variation is allocated and goal with given identifier is found, return UserAssignedInfo with valid information, otherwise, Empty UserAssignedInfo object. /// </returns> private UserAllocationInfo AllocateVariation(string campaignKey, string userId, BucketedCampaign campaign, Dictionary <string, dynamic> customVariables, Dictionary <string, dynamic> variationTargetingVariables, string goalIdentifier, string apiName) { var userAllocationInfo = this.AllocateVariation(campaignKey, userId, campaign, customVariables, variationTargetingVariables, apiName); if (userAllocationInfo.Variation != null) { if (userAllocationInfo.Campaign.Goals.TryGetValue(goalIdentifier, out Goal goal)) { userAllocationInfo.Goal = goal; } else { LogErrorMessage.TrackApiGoalNotFound(file, goalIdentifier, campaignKey, userId); } } else { LogErrorMessage.TrackApiVariationNotFound(file, campaignKey, userId); } return(userAllocationInfo); }
private UserAllocationInfo GetControlVariation(BucketedCampaign campaign, Variation variation) { return(new UserAllocationInfo(variation, campaign)); }
private List <Variation> GetWhiteListedVariationsList(string apiName, string userId, BucketedCampaign campaign, string campaignKey, Dictionary <string, dynamic> customVariables, Dictionary <string, dynamic> variationTargetingVariables) { List <Variation> result = new List <Variation> { }; foreach (var variation in campaign.Variations.All()) { string status = Constants.SegmentationStatus.FAILED; string segmentationType = Constants.SegmentationType.WHITELISTING; if (variation.Segments.Count == 0) { LogDebugMessage.SkippingSegmentation(typeof(IVWOClient).FullName, userId, campaignKey, apiName, variation.Name); } else { if (this._segmentEvaluator.evaluate(userId, campaignKey, segmentationType, variation.Segments, variationTargetingVariables)) { status = Constants.SegmentationStatus.PASSED; result.Add(variation); } LogDebugMessage.SegmentationStatus(typeof(IVWOClient).FullName, userId, campaignKey, apiName, variation.Name, status); } } return(result); }
public Variation GetSavedVariation(BucketedCampaign campaign, string variationName) { return(campaign.Variations.Find(variationName, GetVariationName)); }