@@ -18,7 +18,7 @@ class SplitClient
1818 # @param sdk_key [String] the SDK key for your split account
1919 #
2020 # @return [SplitIoClient] split.io client instance
21- def initialize ( sdk_key , repositories , status_manager , config , impressions_manager , telemetry_evaluation_producer , evaluator , split_validator )
21+ def initialize ( sdk_key , repositories , status_manager , config , impressions_manager , telemetry_evaluation_producer , evaluator , split_validator , fallback_treatment_calculator )
2222 @api_key = sdk_key
2323 @splits_repository = repositories [ :splits ]
2424 @segments_repository = repositories [ :segments ]
@@ -32,6 +32,7 @@ def initialize(sdk_key, repositories, status_manager, config, impressions_manage
3232 @telemetry_evaluation_producer = telemetry_evaluation_producer
3333 @split_validator = split_validator
3434 @evaluator = evaluator
35+ @fallback_treatment_calculator = fallback_treatment_calculator
3536 end
3637
3738 def get_treatment (
@@ -277,7 +278,7 @@ def treatments(key, feature_flag_names, attributes = {}, evaluation_options = ni
277278 if !@config . split_validator . valid_get_treatments_parameters ( calling_method , key , sanitized_feature_flag_names , matching_key , bucketing_key , attributes )
278279 to_return = Hash . new
279280 sanitized_feature_flag_names . each { |name |
280- to_return [ name . to_sym ] = control_treatment_with_config
281+ to_return [ name . to_sym ] = check_fallback_treatment ( name , '' )
281282 }
282283 return to_return
283284 end
@@ -286,9 +287,11 @@ def treatments(key, feature_flag_names, attributes = {}, evaluation_options = ni
286287 impressions = [ ]
287288 to_return = Hash . new
288289 sanitized_feature_flag_names . each { |name |
289- to_return [ name . to_sym ] = control_treatment_with_config
290+ treatment_data = check_fallback_treatment ( name , Engine ::Models ::Label ::NOT_READY )
291+ to_return [ name . to_sym ] = treatment_data
292+
290293 impressions << { :impression => @impressions_manager . build_impression ( matching_key , bucketing_key , name . to_sym ,
291- control_treatment_with_config . merge ( { :label => Engine :: Models :: Label :: NOT_READY } ) , false , { attributes : attributes , time : nil } ,
294+ get_treatment_without_config ( treatment_data ) , false , { attributes : attributes , time : nil } ,
292295 evaluation_options ) , :disabled => false }
293296 }
294297 @impressions_manager . track ( impressions )
@@ -308,7 +311,7 @@ def treatments(key, feature_flag_names, attributes = {}, evaluation_options = ni
308311 if feature_flag . nil?
309312 @config . logger . warn ( "#{ calling_method } : you passed #{ key } that " \
310313 'does not exist in this environment, please double check what feature flags exist in the Split user interface' )
311- invalid_treatments [ key ] = control_treatment_with_config
314+ invalid_treatments [ key ] = check_fallback_treatment ( key , Engine :: Models :: Label :: NOT_FOUND )
312315 next
313316 end
314317 treatments_labels_change_numbers , impressions = evaluate_treatment ( feature_flag , key , bucketing_key , matching_key , attributes , calling_method , false , evaluation_options )
@@ -344,7 +347,7 @@ def treatment(key, feature_flag_name, attributes = {}, split_data = nil, store_i
344347
345348 attributes = parsed_attributes ( attributes )
346349
347- return parsed_treatment ( control_treatment , multiple ) unless valid_client && @config . split_validator . valid_get_treatment_parameters ( calling_method , key , feature_flag_name , matching_key , bucketing_key , attributes )
350+ return parsed_treatment ( check_fallback_treatment ( feature_flag_name , "" ) , multiple ) unless valid_client && @config . split_validator . valid_get_treatment_parameters ( calling_method , key , feature_flag_name , matching_key , bucketing_key , attributes )
348351
349352 bucketing_key = bucketing_key ? bucketing_key . to_s : nil
350353 matching_key = matching_key . to_s
@@ -373,7 +376,7 @@ def evaluate_treatment(feature_flag, feature_flag_name, bucketing_key, matching_
373376 if feature_flag . nil? && ready?
374377 @config . logger . warn ( "#{ calling_method } : you passed #{ feature_flag_name } that " \
375378 'does not exist in this environment, please double check what feature flags exist in the Split user interface' )
376- return parsed_treatment ( control_treatment . merge ( { :label => Engine ::Models ::Label ::NOT_FOUND } ) , multiple ) , nil
379+ return check_fallback_treatment ( feature_flag_name , Engine ::Models ::Label ::NOT_FOUND ) , nil
377380 end
378381
379382 if !feature_flag . nil? && ready?
@@ -383,7 +386,7 @@ def evaluate_treatment(feature_flag, feature_flag_name, bucketing_key, matching_
383386 impressions_disabled = feature_flag [ :impressionsDisabled ]
384387 else
385388 @config . logger . error ( "#{ calling_method } : the SDK is not ready, results may be incorrect for feature flag #{ feature_flag_name } . Make sure to wait for SDK readiness before using this method." )
386- treatment_data = control_treatment . merge ( { :label => Engine ::Models ::Label ::NOT_READY } )
389+ treatment_data = check_fallback_treatment ( feature_flag_name , Engine ::Models ::Label ::NOT_READY )
387390 impressions_disabled = false
388391 end
389392
@@ -396,22 +399,16 @@ def evaluate_treatment(feature_flag, feature_flag_name, bucketing_key, matching_
396399 rescue StandardError => e
397400 @config . log_found_exception ( __method__ . to_s , e )
398401 record_exception ( calling_method )
399- impression_decorator = { :impression => @impressions_manager . build_impression ( matching_key , bucketing_key , feature_flag_name , control_treatment , false , { attributes : attributes , time : nil } , evaluation_options ) , :disabled => false }
402+ treatment_data = check_fallback_treatment ( feature_flag_name , Engine ::Models ::Label ::EXCEPTION )
403+ impression_decorator = { :impression => @impressions_manager . build_impression ( matching_key , bucketing_key , feature_flag_name , get_treatment_without_config ( treatment_data ) , false , { attributes : attributes , time : nil } , evaluation_options ) , :disabled => false }
404+
400405 impressions_decorator << impression_decorator unless impression_decorator . nil?
401406
402- return parsed_treatment ( control_treatment . merge ( { :label => Engine :: Models :: Label :: EXCEPTION } ) , multiple ) , impressions_decorator
407+ return parsed_treatment ( treatment_data , multiple ) , impressions_decorator
403408 end
404409 return parsed_treatment ( treatment_data , multiple ) , impressions_decorator
405410 end
406411
407- def control_treatment
408- { :treatment => Engine ::Models ::Treatment ::CONTROL }
409- end
410-
411- def control_treatment_with_config
412- { :treatment => Engine ::Models ::Treatment ::CONTROL , :config => nil }
413- end
414-
415412 def variable_size ( value )
416413 value . is_a? ( String ) ? value . length : 0
417414 end
@@ -472,5 +469,31 @@ def record_exception(method)
472469 @telemetry_evaluation_producer . record_exception ( Telemetry ::Domain ::Constants ::TRACK )
473470 end
474471 end
472+
473+ def check_fallback_treatment ( feature_name , label )
474+ fallback_treatment = @fallback_treatment_calculator . resolve ( feature_name . to_sym , label )
475+
476+ {
477+ label : fallback_treatment . label ,
478+ treatment : fallback_treatment . treatment ,
479+ config : get_fallback_config ( fallback_treatment )
480+ }
481+ end
482+
483+ def get_treatment_without_config ( treatment )
484+ {
485+ label : treatment [ :label ] ,
486+ treatment : treatment [ :treatment ] ,
487+ }
488+ end
489+
490+ def get_fallback_config ( fallback_treatment )
491+ if fallback_treatment . config != nil
492+ return fallback_treatment . config
493+ end
494+
495+ return nil
496+ end
497+
475498 end
476499end
0 commit comments