Skip to content

Commit dfe97ee

Browse files
Mat001claudeesrakartalOpt
authored
[AI-FSSDK] [FSSDK-12368] Remove legacy flag-level holdout fields (#395)
* [FSSDK-12368] Remove legacy flag-level holdout fields Remove deprecated included_flags and excluded_flags from Holdout model and simplify holdout handling to treat all holdouts as global. - Removed included_flags and excluded_flags from Holdout schema - Removed global_holdouts, included_holdouts_map, excluded_holdouts_map - Simplified holdout initialization to single holdout_map - Updated decision_service to use simplified holdout_map - Removed 13 legacy-specific test cases - Updated test fixtures to remove legacy fields All 1020 tests pass. Verification: grep for included_flags|excluded_flags returns 0 results. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Fix lint issues --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: esrakartalOpt <esra.kartal@optimizely.com>
1 parent c39fea1 commit dfe97ee

6 files changed

Lines changed: 34 additions & 351 deletions

File tree

lib/optimizely/config/datafile_project_config.rb

Lines changed: 1 addition & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ class DatafileProjectConfig < ProjectConfig
3333
:group_id_map, :rollout_id_map, :rollout_experiment_id_map, :variation_id_map,
3434
:variation_id_to_variable_usage_map, :variation_key_map, :variation_id_map_by_experiment_id,
3535
:variation_key_map_by_experiment_id, :flag_variation_map, :integration_key_map, :integrations,
36-
:public_key_for_odp, :host_for_odp, :all_segments, :region, :holdouts, :holdout_id_map,
37-
:global_holdouts, :included_holdouts, :excluded_holdouts, :flag_holdouts_map
36+
:public_key_for_odp, :host_for_odp, :all_segments, :region, :holdouts, :holdout_id_map
3837
# Boolean - denotes if Optimizely should remove the last block of visitors' IP address before storing event data
3938
attr_reader :anonymize_ip
4039

@@ -115,10 +114,6 @@ def initialize(datafile, logger, error_handler)
115114
@variation_id_to_experiment_map = {}
116115
@flag_variation_map = {}
117116
@holdout_id_map = {}
118-
@global_holdouts = []
119-
@included_holdouts = {}
120-
@excluded_holdouts = {}
121-
@flag_holdouts_map = {}
122117

123118
@holdouts.each do |holdout|
124119
next unless holdout['status'] == 'Running'
@@ -127,31 +122,6 @@ def initialize(datafile, logger, error_handler)
127122
holdout['layerId'] ||= ''
128123

129124
@holdout_id_map[holdout['id']] = holdout
130-
131-
included_flags = holdout['includedFlags'] || []
132-
excluded_flags = holdout['excludedFlags'] || []
133-
134-
case [included_flags.empty?, excluded_flags.empty?]
135-
when [true, true]
136-
# No included or excluded flags - this is a global holdout
137-
@global_holdouts << holdout
138-
139-
when [false, true], [false, false]
140-
# Has included flags - add to included_holdouts map
141-
included_flags.each do |flag_id|
142-
@included_holdouts[flag_id] ||= []
143-
@included_holdouts[flag_id] << holdout
144-
end
145-
146-
when [true, false]
147-
# No included flags but has excluded flags - global with exclusions
148-
@global_holdouts << holdout
149-
150-
excluded_flags.each do |flag_id|
151-
@excluded_holdouts[flag_id] ||= []
152-
@excluded_holdouts[flag_id] << holdout
153-
end
154-
end
155125
end
156126

157127
@experiment_id_map.each_value do |exp|
@@ -658,46 +628,6 @@ def rollout_experiment?(experiment_id)
658628
@rollout_experiment_id_map.key?(experiment_id)
659629
end
660630

661-
def get_holdouts_for_flag(flag_id)
662-
# Helper method to get holdouts from an applied feature flag
663-
#
664-
# flag_id - (REQUIRED) ID of the feature flag
665-
# This parameter is required and should not be null/nil
666-
#
667-
# Returns the holdouts that apply for a specific flag
668-
669-
return [] if @holdouts.nil? || @holdouts.empty?
670-
671-
# Check cache first (before validation, so we cache the validation result too)
672-
return @flag_holdouts_map[flag_id] if @flag_holdouts_map.key?(flag_id)
673-
674-
# Validate that the flag exists in the datafile
675-
flag_exists = @feature_flags.any? { |flag| flag['id'] == flag_id }
676-
unless flag_exists
677-
# Cache the empty result for non-existent flags
678-
@flag_holdouts_map[flag_id] = []
679-
return []
680-
end
681-
682-
# Prioritize global holdouts first
683-
excluded = @excluded_holdouts[flag_id] || []
684-
685-
active_holdouts = if excluded.any?
686-
@global_holdouts.reject { |holdout| excluded.include?(holdout) }
687-
else
688-
@global_holdouts.dup
689-
end
690-
691-
# Append included holdouts
692-
included = @included_holdouts[flag_id] || []
693-
active_holdouts.concat(included)
694-
695-
# Cache the result
696-
@flag_holdouts_map[flag_id] = active_holdouts
697-
698-
@flag_holdouts_map[flag_id] || []
699-
end
700-
701631
def get_holdout(holdout_id)
702632
# Helper method to get holdout from holdout ID
703633
#

lib/optimizely/decision_service.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,10 @@ def get_variation_for_feature(project_config, feature_flag, user_context, decide
169169
# user_context - Optimizely user context instance
170170
#
171171
# Returns DecisionResult struct.
172-
holdouts = project_config.get_holdouts_for_flag(feature_flag['id'])
172+
# Get running holdouts from the holdout_id_map (all holdouts are global now)
173+
running_holdouts = project_config.holdout_id_map.values
173174

174-
if holdouts && !holdouts.empty?
175+
if running_holdouts && !running_holdouts.empty?
175176
# Has holdouts - use get_decision_for_flag which checks holdouts first
176177
get_decision_for_flag(feature_flag, user_context, project_config, decide_options)
177178
else
@@ -195,8 +196,8 @@ def get_decision_for_flag(feature_flag, user_context, project_config, decide_opt
195196
reasons = decide_reasons ? decide_reasons.dup : []
196197
user_id = user_context.user_id
197198

198-
# Check holdouts
199-
holdouts = project_config.get_holdouts_for_flag(feature_flag['id'])
199+
# Check holdouts (all holdouts are global now - apply to all flags)
200+
holdouts = project_config.holdout_id_map.values
200201

201202
holdouts.each do |holdout|
202203
holdout_decision = get_variation_for_holdout(holdout, user_context, project_config)

lib/optimizely/helpers/constants.rb

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -346,14 +346,6 @@ module Constants
346346
},
347347
'status' => {
348348
'type' => 'string'
349-
},
350-
'includedFlags' => {
351-
'type' => 'array',
352-
'items' => {'type' => 'string'}
353-
},
354-
'excludedFlags' => {
355-
'type' => 'array',
356-
'items' => {'type' => 'string'}
357349
}
358350
}
359351
}

0 commit comments

Comments
 (0)