@@ -31,22 +31,22 @@ var DECISION_SOURCES = enums.DECISION_SOURCES;
3131
3232
3333/**
34- * Optimizely's decision service that determines which variation of an experiment the user will be allocated to .
34+ * A decision service that determines which variation of an experiment to which to allocate a user .
3535 *
36- * The decision service contains all logic around how a user decision is made. This includes all of the following ( in order) :
37- * 1. Checking experiment status
38- * 2. Checking forced bucketing
39- * 3. Checking whitelisting
40- * 4. Checking user profile service for past bucketing decisions (sticky bucketing)
41- * 5. Checking audience targeting
42- * 6. Using Murmurhash3 to bucket the user.
36+ * The decision service contains all logic determining how a user decision is made. The following tasks are performed in order:
37+ * 1. Check the experiment status.
38+ * 2. Check for forced bucketing.
39+ * 3. Check for whitelisting.
40+ * 4. Check the user profile service for past bucketing decisions (sticky bucketing).
41+ * 5. Check for audience targeting.
42+ * 6. Bucket the user.
4343 *
4444 * @constructor
45- * @param {Object } options
46- * @param {Object } options.configObj The parsed project configuration object that contains all the experiment configurations.
47- * @param {Object } options.userProfileService An instance of the user profile service for sticky bucketing.
48- * @param {Object } options.logger An instance of a logger to log messages with .
49- * @returns {Object }
45+ * @param {object } options The parsed project configuration object.
46+ * @param {object } options.configObj The parsed project configuration object that contains all of the experiment configurations.
47+ * @param {object } options.userProfileService An instance of the user profile service for sticky bucketing.
48+ * @param {object } options.logger An instance of a logger used to log messages.
49+ * @returns {object }
5050 */
5151function DecisionService ( options ) {
5252 this . configObj = options . configObj ;
@@ -55,11 +55,11 @@ function DecisionService(options) {
5555}
5656
5757/**
58- * Gets variation where visitor will be bucketed.
59- * @param {string } experimentKey
60- * @param {string } userId
61- * @param {Object } attributes
62- * @return {string|null } the variation the user is bucketed into .
58+ * Returns a variation where the visitor will be bucketed.
59+ * @param {string } experimentKey The ID of the experiment for which to get the variation.
60+ * @param {string } userId The ID of the visitor.
61+ * @param {object } attributes A collection of key/value pairs of user attributes.
62+ * @return {string|null } The variation into which the user is bucketed.
6363 */
6464DecisionService . prototype . getVariation = function ( experimentKey , userId , attributes ) {
6565 // by default, the bucketing ID should be the user ID
@@ -106,9 +106,10 @@ DecisionService.prototype.getVariation = function(experimentKey, userId, attribu
106106} ;
107107
108108/**
109- * Merges attributes from attributes[STICKY_BUCKETING_KEY] and userProfileService
110- * @param {Object } attributes
111- * @return {Object } finalized copy of experiment_bucket_map
109+ * Merges attributes from 'attributes[STICKY_BUCKETING_KEY]' and 'userProfileService'.
110+ * @param {string } userId The ID of the user.
111+ * @param {object } attributes An optional key/value pair collection containing user attributes.
112+ * @return {object } A finalized copy of 'experiment_bucket_map' from the user's profile.
112113 */
113114DecisionService . prototype . __resolveExperimentBucketMap = function ( userId , attributes ) {
114115 attributes = attributes || { }
@@ -119,10 +120,10 @@ DecisionService.prototype.__resolveExperimentBucketMap = function(userId, attrib
119120
120121
121122/**
122- * Checks whether the experiment is running or launched
123- * @param {string } experimentKey Key of experiment being validated
124- * @param {string } userId ID of user
125- * @return {boolean } True if experiment is running
123+ * Checks whether the experiment is running or launched.
124+ * @param {string } experimentKey The ID of the of experiment being validated.
125+ * @param {string } userId The ID of the user.
126+ * @return {boolean } `true` if the experiment is running, `false` if the experiment is not running.
126127 */
127128DecisionService . prototype . __checkIfExperimentIsActive = function ( experimentKey , userId ) {
128129 if ( ! projectConfig . isActive ( this . configObj , experimentKey ) ) {
@@ -135,10 +136,10 @@ DecisionService.prototype.__checkIfExperimentIsActive = function(experimentKey,
135136} ;
136137
137138/**
138- * Checks if user is whitelisted into any variation and return that variation if so
139- * @param {Object } experiment
140- * @param {string } userId
141- * @return {string|null } Forced variation if it exists for user ID, otherwise null
139+ * Checks if a user is whitelisted into any variation, and returns that variation.
140+ * @param {Object } experiment The experiment to check for any forced variations.
141+ * @param {string } userId The ID of the user for whom to get the variation.
142+ * @return {string|null } The forced variation, if it exists, for the specified user ID; ` null` otherwise.
142143 */
143144DecisionService . prototype . __getWhitelistedVariation = function ( experiment , userId ) {
144145 if ( ! fns . isEmpty ( experiment . forcedVariations ) && experiment . forcedVariations . hasOwnProperty ( userId ) ) {
@@ -158,11 +159,11 @@ DecisionService.prototype.__getWhitelistedVariation = function(experiment, userI
158159} ;
159160
160161/**
161- * Checks whether the user is included in experiment audience
162- * @param {string } experimentKey Key of experiment being validated
163- * @param {string } userId ID of user
164- * @param {Object } attributes Optional parameter for user's attributes
165- * @return {boolean } True if user meets audience conditions
162+ * Checks if a user is included in an experiment's audience.
163+ * @param {string } experimentKey The ID of the experiment being validated.
164+ * @param {string } userId The ID of the user to check.
165+ * @param {Object } attributes An optional key/value pair collection containing user attributes.
166+ * @return {boolean } `true` if the user meets audience conditions; `false` otherwise.
166167 */
167168DecisionService . prototype . __checkIfUserIsInAudience = function ( experimentKey , userId , attributes ) {
168169 var experimentAudienceConditions = projectConfig . getExperimentAudienceConditions ( this . configObj , experimentKey ) ;
@@ -177,11 +178,11 @@ DecisionService.prototype.__checkIfUserIsInAudience = function(experimentKey, us
177178} ;
178179
179180/**
180- * Given an experiment key and user ID, returns params used in bucketer call
181- * @param experimentKey Experiment key used for bucketer
182- * @param bucketingId ID to bucket user into
183- * @param userId ID of user to be bucketed
184- * @return {Object }
181+ * Retrieves the parameters used in the bucketer call for a given experiment key and user ID.
182+ * @param { string } experimentKey The ID of the experiment used for the bucketer.
183+ * @param { string } bucketingId The ID into which to bucket the user.
184+ * @param { string } userId The ID of the user to be bucketed.
185+ * @return {Object } An object containing the bucketer parameters.
185186 */
186187DecisionService . prototype . __buildBucketerParams = function ( experimentKey , bucketingId , userId ) {
187188 var bucketerParams = { } ;
@@ -198,11 +199,11 @@ DecisionService.prototype.__buildBucketerParams = function(experimentKey, bucket
198199} ;
199200
200201/**
201- * Pull the stored variation out of the experimentBucketMap for an experiment/userId
202- * @param {Object } experiment
203- * @param {String } userId
204- * @param {Object } experimentBucketMap mapping experiment => { variation_id: <variationId> }
205- * @return {Object } the stored variation or null if the user profile does not have one for the given experiment
202+ * Retrieves the stored variation for the specified experiment and user.
203+ * @param {Object } experiment The ID of the experiment from which to get the variation.
204+ * @param {String } userId The ID of the user for whom to get the variation,
205+ * @param {Object } experimentBucketMap A mapping between an experiment ID and variation ID.
206+ * @return {Object } The stored variation, or ` null` if the user profile does not have a variation for the experiment.
206207 */
207208DecisionService . prototype . __getStoredVariation = function ( experiment , userId , experimentBucketMap ) {
208209 if ( experimentBucketMap . hasOwnProperty ( experiment . id ) ) {
@@ -219,9 +220,9 @@ DecisionService.prototype.__getStoredVariation = function(experiment, userId, ex
219220} ;
220221
221222/**
222- * Get the user profile with the given user ID
223- * @param {string } userId
224- * @return {Object|undefined } the stored user profile or undefined if one isn't found
223+ * Retrieves the user profile for a specific user.
224+ * @param {string } userId The ID of the user.
225+ * @return {Object|undefined } The stored user profile, or ' undefined' if one isn't found.
225226 */
226227DecisionService . prototype . __getUserProfile = function ( userId ) {
227228 var userProfile = {
@@ -241,11 +242,11 @@ DecisionService.prototype.__getUserProfile = function(userId) {
241242} ;
242243
243244/**
244- * Saves the bucketing decision to the user profile
245- * @param {Object } userProfile
246- * @param {Object } experiment
247- * @param {Object } variation
248- * @param {Object } experimentBucketMap
245+ * Saves the bucketing decision to the user profile.
246+ * @param {Object } experiment The experiment for which to save the bucketing decision.
247+ * @param {Object } variation The variation for which to save the bucketing decision.
248+ * @param {String } userId The ID of the user.
249+ * @param {Object } experimentBucketMap An object that maps an experiment ID to a variation ID.
249250 */
250251DecisionService . prototype . __saveUserProfile = function ( experiment , variation , userId , experimentBucketMap ) {
251252 if ( ! this . userProfileService ) {
@@ -270,18 +271,16 @@ DecisionService.prototype.__saveUserProfile = function(experiment, variation, us
270271} ;
271272
272273/**
273- * Given a feature, user ID, and attributes, returns an object representing a
274- * decision. If the user was bucketed into a variation for the given feature
275- * and attributes, the returned decision object will have variation and
276- * experiment properties (both objects), as well as a decisionSource property.
277- * decisionSource indicates whether the decision was due to a rollout or an
278- * experiment.
279- * @param {Object } feature A feature flag object from project configuration
280- * @param {String } userId A string identifying the user, for bucketing
281- * @param {Object } attributes Optional user attributes
282- * @return {Object } An object with experiment, variation, and decisionSource
283- * properties. If the user was not bucketed into a variation, the variation
284- * property is null.
274+ * Retrieves an object containing a decision for a specific feature, user ID, and attributes.
275+ * If the user was bucketed into a variation for the specified feature
276+ * and attributes, the decision object returned will have both 'variation' and
277+ * 'experiment' properties, as well as a 'decisionSource' property.
278+ * 'decisionSource' indicates whether the decision was due to a rollout for an experiment.
279+ * @param {Object } feature The feature flag object from a project configuration.
280+ * @param {String } userId The ID of the user.
281+ * @param {Object } attributes An optional key/value pair collection containing user attributes.
282+ * @return {Object } An object containing 'experiment', 'variation', and 'decisionSource' properties.
283+ * If the user was not bucketed into a variation, the 'variation' property is null.
285284 */
286285DecisionService . prototype . getVariationForFeature = function ( feature , userId , attributes ) {
287286 var experimentDecision = this . _getVariationForFeatureExperiment ( feature , userId , attributes ) ;
@@ -307,6 +306,14 @@ DecisionService.prototype.getVariationForFeature = function(feature, userId, att
307306 } ;
308307} ;
309308
309+ /**
310+ * Retrieves an object containing a variation for a specific experiment.
311+ * @param {Object } feature The feature flag object from a project configuration.
312+ * @param {String } userId The ID of the user for the variation.
313+ * @param {Object } attributes An optional key/value pair collection containing user attributes.
314+ * @return {Object } An object containing 'experiment', 'variation', and 'decisionSource' properties.
315+ * If the user was not bucketed into a variation, the variation property is null.
316+ */
310317DecisionService . prototype . _getVariationForFeatureExperiment = function ( feature , userId , attributes ) {
311318 var experiment = null ;
312319 var variationKey = null ;
@@ -341,6 +348,7 @@ DecisionService.prototype._getVariationForFeatureExperiment = function(feature,
341348 } ;
342349} ;
343350
351+
344352DecisionService . prototype . _getExperimentInGroup = function ( group , userId ) {
345353 var experimentId = bucketer . bucketUserIntoExperiment ( group , userId , userId , this . logger ) ;
346354 if ( experimentId !== null ) {
@@ -355,6 +363,14 @@ DecisionService.prototype._getExperimentInGroup = function(group, userId) {
355363 return null ;
356364} ;
357365
366+ /**
367+ * Retrieves a variation for a specific feature rollout.
368+ * @param {Object } feature The feature flag object from a project configuration.
369+ * @param {String } userId The ID of the user for the variation.
370+ * @param {Object } attributes An optional key/value pair collection containing user attributes.
371+ * @return {Object } An object containing 'experiment', 'variation', and 'decisionSource' properties.
372+ * If the user was not bucketed into a variation, the variation property is null. If there are no experiments in the rollout, the experiment property is null.
373+ */
358374DecisionService . prototype . _getVariationForRollout = function ( feature , userId , attributes ) {
359375 if ( ! feature . rolloutId ) {
360376 this . logger . log ( LOG_LEVEL . DEBUG , sprintf ( LOG_MESSAGES . NO_ROLLOUT_EXISTS , MODULE_NAME , feature . key ) ) ;
@@ -442,10 +458,10 @@ DecisionService.prototype._getVariationForRollout = function(feature, userId, at
442458} ;
443459
444460/**
445- * Get bucketing Id from user attributes.
446- * @param {String } userId
447- * @param {Object } attributes
448- * @returns {String } Bucketing Id if it is a string type in attributes, user Id otherwise .
461+ * Retrieves a bucketing ID for a specific user ID and user attributes.
462+ * @param {String } userId The ID of the user for the variation.
463+ * @param {Object } attributes An optional key/value pair collection containing user attributes.
464+ * @returns {String } The bucketing ID if it available in the attributes; otherwise the user ID is returned .
449465 */
450466DecisionService . prototype . _getBucketingId = function ( userId , attributes ) {
451467 var bucketingId = userId ;
@@ -465,12 +481,12 @@ DecisionService.prototype._getBucketingId = function(userId, attributes) {
465481
466482module . exports = {
467483 /**
468- * Creates an instance of the DecisionService .
469- * @param {Object } options Configuration options
470- * @param {Object } options.configObj
471- * @param {Object } options.userProfileService
472- * @param {Object } options.logger
473- * @return {Object } An instance of the DecisionService
484+ * Creates an instance of the decision service .
485+ * @param {Object } options Configuration options.
486+ * @param {Object } options.configObj The parsed project configuration object that contains all of the experiment configurations.
487+ * @param {Object } options.userProfileService An instance of the user profile service for sticky bucketing.
488+ * @param {Object } options.logger An instance of a logger used to log messages.
489+ * @return {Object } An instance of the decision service.
474490 */
475491 createDecisionService : function ( options ) {
476492 return new DecisionService ( options ) ;
0 commit comments