class VWO::BucketingService
Constants
- FILE
- MAX_HASH_VALUE
- U_MAX_32_BIT
Public Class Methods
# File lib/vwo/bucketing_service.rb, line 20 def initialize @logger = CustomLogger.get_instance end
Public Instance Methods
Validates the User ID and Generates Variation into which the User is bucketed in.
@param :user_id The unique ID assigned to User @param :campaign The Campaign of which User is a part of
@return[Hash|nil} Variation data into which user is bucketed in
or nil if not
# File lib/vwo/bucketing_service.rb, line 65 def bucket_user_to_variation(user_id, campaign) unless valid_value?(user_id) @logger.log( LogLevelEnum::ERROR, format(LogMessageEnum::ErrorMessages::INVALID_USER_ID, file: FILE, user_id: user_id, method: 'bucket_user_to_variation') ) return end unless campaign @logger.log( LogLevelEnum::ERROR, format(LogMessageEnum::ErrorMessages::INVALID_CAMPAIGN, file: FILE, method: 'is_user_part_of_campaign') ) return end hash_value = MurmurHash3::V32.str_hash(user_id, SEED_VALUE) & U_MAX_32_BIT normalize = MAX_TRAFFIC_VALUE / campaign['percentTraffic'] multiplier = normalize / 100 bucket_value = generate_bucket_value( hash_value, MAX_TRAFFIC_VALUE, multiplier ) @logger.log( LogLevelEnum::DEBUG, format( LogMessageEnum::DebugMessages::VARIATION_HASH_BUCKET_VALUE, file: FILE, user_id: user_id, campaign_test_key: campaign['key'], percent_traffic: campaign['percentTraffic'], bucket_value: bucket_value, hash_value: hash_value ) ) get_variation(campaign, bucket_value) end
Calculate if this user should become part of the campaign or not @param :user_id The unique ID assigned to a user @param :campaign For getting traffic allotted to the campaign @return If User is a part of Campaign or not
# File lib/vwo/bucketing_service.rb, line 29 def user_part_of_campaign?(user_id, campaign) unless valid_value?(user_id) @logger.log( LogLevelEnum::ERROR, format(LogMessageEnum::ErrorMessages::INVALID_USER_ID, file: FILE, user_id: user_id, method: 'is_user_part_of_campaign') ) return false end if campaign.nil? @logger.log( LogLevelEnum::ERROR, format(LogMessageEnum::ErrorMessages::INVALID_CAMPAIGN, file: FILE, method: 'is_user_part_of_campaign') ) return false end traffic_allocation = campaign['percentTraffic'] value_assigned_to_user = get_bucket_value_for_user(user_id) is_user_part = (value_assigned_to_user != 0) && value_assigned_to_user <= traffic_allocation @logger.log( LogLevelEnum::INFO, format(LogMessageEnum::InfoMessages::USER_ELIGIBILITY_FOR_CAMPAIGN, file: FILE, user_id: user_id, is_user_part: is_user_part) ) is_user_part end
Private Instance Methods
Generates Bucket Value of the User by hashing the User ID by murmurHash And scaling it down.
@param :hash_value HashValue generated after hashing @param :max_value The value up-to which hashValue needs to be scaled @param :multiplier @return Bucket Value of the User
# File lib/vwo/bucketing_service.rb, line 152 def generate_bucket_value(hash_value, max_value, multiplier = 1) ratio = hash_value.to_f / MAX_HASH_VALUE multiplied_value = (max_value * ratio + 1) * multiplier multiplied_value.to_i end
Validates the User ID and generates Bucket Value of the User by hashing the userId by murmurHash and scaling it down.
@param :user_id The unique ID assigned to User @return The bucket Value allotted to User
(between 1 to $this->$MAX_TRAFFIC_PERCENT)
# File lib/vwo/bucketing_service.rb, line 127 def get_bucket_value_for_user(user_id) hash_value = MurmurHash3::V32.str_hash(user_id, SEED_VALUE) & U_MAX_32_BIT bucket_value = generate_bucket_value(hash_value, MAX_TRAFFIC_PERCENT) @logger.log( LogLevelEnum::DEBUG, format( LogMessageEnum::DebugMessages::USER_HASH_BUCKET_VALUE, file: FILE, hash_value: hash_value, bucket_value: bucket_value, user_id: user_id ) ) bucket_value end
Returns the Variation by checking the Start and End Bucket Allocations of each Variation
@param :campaign Which contains the variations @param :bucket_value The bucket Value of the user @return Variation data allotted to the user or None if not
# File lib/vwo/bucketing_service.rb, line 115 def get_variation(campaign, bucket_value) campaign['variations'].find do |variation| (variation['start_variation_allocation']..variation['end_variation_allocation']).cover?(bucket_value) end end