Skip to content

Commit db656f1

Browse files
fix holdout logic
1 parent 1b28d2e commit db656f1

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

lib/optimizely/config/datafile_project_config.rb

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ def initialize(datafile, logger, error_handler)
115115
@variation_id_to_experiment_map = {}
116116
@flag_variation_map = {}
117117
@holdout_id_map = {}
118-
@global_holdouts = {}
118+
@global_holdouts = []
119119
@included_holdouts = {}
120120
@excluded_holdouts = {}
121121
@flag_holdouts_map = {}
@@ -126,7 +126,7 @@ def initialize(datafile, logger, error_handler)
126126
@holdout_id_map[holdout['id']] = holdout
127127

128128
if holdout['includedFlags'].nil? || holdout['includedFlags'].empty?
129-
@global_holdouts[holdout['id']] = holdout
129+
@global_holdouts << holdout
130130

131131
excluded_flags = holdout['excludedFlags']
132132
if excluded_flags && !excluded_flags.empty?
@@ -197,22 +197,27 @@ def initialize(datafile, logger, error_handler)
197197

198198
flag_id = feature_flag['id']
199199

200-
# Prefer explicit holdouts (includedFlags) over global holdouts
201-
# If multiple explicit holdouts exist, use the first one (deterministic based on datafile order)
202-
applicable_holdout = @included_holdouts[flag_id]&.first
203-
204-
# Use first global holdout that doesn't exclude this flag if no explicit holdout
205-
unless applicable_holdout
206-
@global_holdouts.each_value do |holdout|
207-
excluded_flag_ids = holdout['excludedFlags'] || []
208-
unless excluded_flag_ids.include?(flag_id)
209-
applicable_holdout = holdout
210-
break
211-
end
200+
# Collect all applicable holdouts for this flag
201+
# Priority: global holdouts (excluding excluded flags) + included holdouts
202+
applicable_holdouts = []
203+
204+
# Add all global holdouts that don't exclude this flag
205+
excluded_for_flag = @excluded_holdouts[flag_id] || []
206+
if excluded_for_flag.empty?
207+
# No exclusions, add all global holdouts
208+
applicable_holdouts.concat(@global_holdouts)
209+
else
210+
# Filter out excluded holdouts
211+
@global_holdouts.each do |holdout|
212+
applicable_holdouts << holdout unless excluded_for_flag.include?(holdout)
212213
end
213214
end
214215

215-
@flag_holdouts_map[key] = [applicable_holdout] if applicable_holdout
216+
# Add all included holdouts for this flag
217+
included = @included_holdouts[flag_id]
218+
applicable_holdouts.concat(included) if included && !included.empty?
219+
220+
@flag_holdouts_map[flag_id] = applicable_holdouts unless applicable_holdouts.empty?
216221
end
217222

218223
# Adding Holdout variations in variation id and key maps

0 commit comments

Comments
 (0)