@@ -101,15 +101,34 @@ def get_variation_for_feature(feature_flag, user_id, attributes = nil)
101
101
102
102
# check if the feature is being experiment on and whether the user is bucketed into the experiment
103
103
decision = get_variation_for_feature_experiment ( feature_flag , user_id , attributes )
104
- return decision
104
+ unless decision . nil?
105
+ return decision
106
+ end
105
107
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
108
126
109
- private
127
+ return nil
128
+ end
110
129
111
130
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.
113
132
#
114
133
# feature_flag - The feature flag the user wants to access
115
134
# user_id - String ID for the user
@@ -178,6 +197,90 @@ def get_variation_for_feature_experiment(feature_flag, user_id, attributes = nil
178
197
return nil
179
198
end
180
199
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
+
181
284
def get_forced_variation_id ( experiment_key , user_id )
182
285
# Determine if a user is forced into a variation for the given experiment and return the ID of that variation
183
286
#
0 commit comments