|
43 | 43 | require_relative 'optimizely/odp/odp_manager'
|
44 | 44 | require_relative 'optimizely/helpers/sdk_settings'
|
45 | 45 | require_relative 'optimizely/user_profile_tracker'
|
| 46 | +require_relative 'optimizely/cmab/cmab_client' |
| 47 | +require_relative 'optimizely/cmab/cmab_service' |
46 | 48 |
|
47 | 49 | module Optimizely
|
48 | 50 | class Project
|
49 | 51 | include Optimizely::Decide
|
50 | 52 |
|
| 53 | + # CMAB Constants |
| 54 | + DEFAULT_CMAB_CACHE_TIMEOUT = (30 * 60 * 1000) |
| 55 | + DEFAULT_CMAB_CACHE_SIZE = 1000 |
| 56 | + |
51 | 57 | attr_reader :notification_center
|
52 | 58 | # @api no-doc
|
53 | 59 | attr_reader :config_manager, :decision_service, :error_handler, :event_dispatcher,
|
@@ -131,7 +137,19 @@ def initialize(
|
131 | 137 |
|
132 | 138 | setup_odp!(@config_manager.sdk_key)
|
133 | 139 |
|
134 |
| - @decision_service = DecisionService.new(@logger, @user_profile_service) |
| 140 | + # Initialize CMAB components |
| 141 | + @cmab_client = DefaultCmabClient.new( |
| 142 | + retry_config: CmabRetryConfig.new, |
| 143 | + logger: @logger |
| 144 | + ) |
| 145 | + @cmab_cache = LRUCache.new(DEFAULT_CMAB_CACHE_SIZE, DEFAULT_CMAB_CACHE_TIMEOUT) |
| 146 | + @cmab_service = DefaultCmabService.new( |
| 147 | + @cmab_cache, |
| 148 | + @cmab_client, |
| 149 | + @logger |
| 150 | + ) |
| 151 | + |
| 152 | + @decision_service = DecisionService.new(@logger, @cmab_service, @user_profile_service) |
135 | 153 |
|
136 | 154 | @event_processor = if event_processor.respond_to?(:process)
|
137 | 155 | event_processor
|
@@ -358,9 +376,17 @@ def decide_for_keys(user_context, keys, decide_options = [], ignore_default_opti
|
358 | 376 | decision_list = @decision_service.get_variations_for_feature_list(config, flags_without_forced_decision, user_context, decide_options)
|
359 | 377 |
|
360 | 378 | flags_without_forced_decision.each_with_index do |flag, i|
|
361 |
| - decision = decision_list[i][0] |
362 |
| - reasons = decision_list[i][1] |
| 379 | + decision = decision_list[i].decision |
| 380 | + reasons = decision_list[i].reasons |
| 381 | + error = decision_list[i].error |
363 | 382 | flag_key = flag['key']
|
| 383 | + # store error decision against key and remove key from valid keys |
| 384 | + if error |
| 385 | + optimizely_decision = OptimizelyDecision.new_error_decision(flag_key, user_context, reasons) |
| 386 | + decisions[flag_key] = optimizely_decision |
| 387 | + valid_keys.delete(flag_key) if valid_keys.include?(flag_key) |
| 388 | + next |
| 389 | + end |
364 | 390 | flag_decisions[flag_key] = decision
|
365 | 391 | decision_reasons_dict[flag_key] ||= []
|
366 | 392 | decision_reasons_dict[flag_key].push(*reasons)
|
@@ -599,8 +625,8 @@ def is_feature_enabled(feature_flag_key, user_id, attributes = nil)
|
599 | 625 | end
|
600 | 626 |
|
601 | 627 | user_context = OptimizelyUserContext.new(self, user_id, attributes, identify: false)
|
602 |
| - decision, = @decision_service.get_variation_for_feature(config, feature_flag, user_context) |
603 |
| - |
| 628 | + decision_result = @decision_service.get_variation_for_feature(config, feature_flag, user_context) |
| 629 | + decision = decision_result.decision |
604 | 630 | feature_enabled = false
|
605 | 631 | source_string = Optimizely::DecisionService::DECISION_SOURCES['ROLLOUT']
|
606 | 632 | if decision.is_a?(Optimizely::DecisionService::Decision)
|
@@ -839,7 +865,8 @@ def get_all_feature_variables(feature_flag_key, user_id, attributes = nil)
|
839 | 865 | end
|
840 | 866 |
|
841 | 867 | user_context = OptimizelyUserContext.new(self, user_id, attributes, identify: false)
|
842 |
| - decision, = @decision_service.get_variation_for_feature(config, feature_flag, user_context) |
| 868 | + decision_result = @decision_service.get_variation_for_feature(config, feature_flag, user_context) |
| 869 | + decision = decision_result.decision |
843 | 870 | variation = decision ? decision['variation'] : nil
|
844 | 871 | feature_enabled = variation ? variation['featureEnabled'] : false
|
845 | 872 | all_variables = {}
|
@@ -1029,7 +1056,8 @@ def get_variation_with_config(experiment_key, user_id, attributes, config)
|
1029 | 1056 | user_context = OptimizelyUserContext.new(self, user_id, attributes, identify: false)
|
1030 | 1057 | user_profile_tracker = UserProfileTracker.new(user_id, @user_profile_service, @logger)
|
1031 | 1058 | user_profile_tracker.load_user_profile
|
1032 |
| - variation_id, = @decision_service.get_variation(config, experiment_id, user_context, user_profile_tracker) |
| 1059 | + variation_result = @decision_service.get_variation(config, experiment_id, user_context, user_profile_tracker) |
| 1060 | + variation_id = variation_result.variation_id |
1033 | 1061 | user_profile_tracker.save_user_profile
|
1034 | 1062 | variation = config.get_variation_from_id(experiment_key, variation_id) unless variation_id.nil?
|
1035 | 1063 | variation_key = variation['key'] if variation
|
@@ -1097,7 +1125,8 @@ def get_feature_variable_for_type(feature_flag_key, variable_key, variable_type,
|
1097 | 1125 | end
|
1098 | 1126 |
|
1099 | 1127 | user_context = OptimizelyUserContext.new(self, user_id, attributes, identify: false)
|
1100 |
| - decision, = @decision_service.get_variation_for_feature(config, feature_flag, user_context) |
| 1128 | + decision_result = @decision_service.get_variation_for_feature(config, feature_flag, user_context) |
| 1129 | + decision = decision_result.decision |
1101 | 1130 | variation = decision ? decision['variation'] : nil
|
1102 | 1131 | feature_enabled = variation ? variation['featureEnabled'] : false
|
1103 | 1132 |
|
|
0 commit comments