@@ -101,15 +101,34 @@ def get_variation_for_feature(feature_flag, user_id, attributes = nil)
101101
102102 # check if the feature is being experiment on and whether the user is bucketed into the experiment
103103 decision = get_variation_for_feature_experiment ( feature_flag , user_id , attributes )
104- return decision
104+ unless decision . nil?
105+ return decision
106+ end
105107
106- # @TODO(mng) next check if the user feature being rolled out and whether the user is part of the rollout
107- end
108+ feature_flag_key = feature_flag [ 'key' ]
109+ variation = get_variation_for_feature_rollout ( feature_flag , user_id , attributes )
110+ if variation
111+ @config . logger . log (
112+ Logger ::INFO ,
113+ "User '#{ user_id } ' is in the rollout for feature flag '#{ feature_flag_key } '."
114+ )
115+ # return decision with nil experiment so we don't track impressions for it
116+ return {
117+ 'experiment' => nil ,
118+ 'variation' => variation
119+ }
120+ else
121+ @config . logger . log (
122+ Logger ::INFO ,
123+ "User '#{ user_id } ' is not in the rollout for feature flag '#{ feature_flag_key } '."
124+ )
125+ end
108126
109- private
127+ return nil
128+ end
110129
111130 def get_variation_for_feature_experiment ( feature_flag , user_id , attributes = nil )
112- # Gets the variation the user is bucketed into for the feature flag's experiment
131+ # Gets the variation the user is bucketed into for the feature flag's experiment.
113132 #
114133 # feature_flag - The feature flag the user wants to access
115134 # user_id - String ID for the user
@@ -178,6 +197,90 @@ def get_variation_for_feature_experiment(feature_flag, user_id, attributes = nil
178197 return nil
179198 end
180199
200+ def get_variation_for_feature_rollout ( feature_flag , user_id , attributes = nil )
201+ # Determine which variation the user is in for a given rollout.
202+ # Returns the variation of the first experiment the user qualifies for.
203+ #
204+ # feature_flag - The feature flag the user wants to access
205+ # user_id - String ID for the user
206+ # attributes - Hash representing user attributes
207+ #
208+ # Returns the variation the user is bucketed into or nil if not bucketed into any of the targeting rules
209+
210+ rollout_id = feature_flag [ 'rolloutId' ]
211+ if rollout_id . nil? or rollout_id . empty?
212+ feature_flag_key = feature_flag [ 'key' ]
213+ @config . logger . log (
214+ Logger ::DEBUG ,
215+ "Feature flag '#{ feature_flag_key } ' is not part of a rollout."
216+ )
217+ return nil
218+ end
219+
220+ rollout = @config . get_rollout_from_id ( rollout_id )
221+ unless rollout . nil? or rollout [ 'experiments' ] . empty?
222+ rollout_experiments = rollout [ 'experiments' ]
223+ number_of_rules = rollout_experiments . length - 1
224+
225+ # Go through each experiment in order and try to get the variation for the user
226+ for index in ( 0 ...number_of_rules )
227+ experiment = rollout_experiments [ index ]
228+ experiment_key = experiment [ 'key' ]
229+
230+ # Check that user meets audience conditions for targeting rule
231+ unless Audience . user_in_experiment? ( @config , experiment , attributes )
232+ @config . logger . log (
233+ Logger ::DEBUG ,
234+ "User '#{ user_id } ' does not meet the conditions to be in experiment '#{ experiment_key } '."
235+ )
236+ # move onto the next targeting rule
237+ next
238+ end
239+
240+ @config . logger . log (
241+ Logger ::DEBUG ,
242+ "User '#{ user_id } ' meets conditions for targeting rule '#{ index + 1 } '."
243+ )
244+ variation = @bucketer . bucket ( experiment , user_id )
245+ unless variation . nil?
246+ variation_key = variation [ 'key' ]
247+ @config . logger . log (
248+ Logger ::DEBUG ,
249+ "User '#{ user_id } ' is in variation '#{ variation_key } ' of experiment '#{ experiment_key } '."
250+ )
251+ return variation
252+ end
253+
254+ # User failed traffic allocation, jump to Everyone Else rule
255+ @config . logger . log (
256+ Logger ::DEBUG ,
257+ "User '#{ user_id } ' is not in the traffic group for the targeting rule. Checking 'Eveyrone Else' rule now."
258+ )
259+ break
260+ end
261+
262+ # Evalute the "Everyone Else" rule, which is the last rule.
263+ everyone_else_experiment = rollout_experiments [ number_of_rules ]
264+ variation = @bucketer . bucket ( everyone_else_experiment , user_id )
265+ unless variation . nil?
266+ @config . logger . log (
267+ Logger ::DEBUG ,
268+ "User '#{ user_id } ' meets conditions for targeting rule 'Everyone Else'."
269+ )
270+ return variation
271+ end
272+
273+ @config . logger . log (
274+ Logger ::DEBUG ,
275+ "User '#{ user_id } ' does not meet conditions for targeting rule 'Everyone Else'."
276+ )
277+ end
278+
279+ return nil
280+ end
281+
282+ private
283+
181284 def get_forced_variation_id ( experiment_key , user_id )
182285 # Determine if a user is forced into a variation for the given experiment and return the ID of that variation
183286 #
0 commit comments