38
38
require_relative 'optimizely/notification_center'
39
39
require_relative 'optimizely/optimizely_config'
40
40
require_relative 'optimizely/optimizely_user_context'
41
+ require_relative 'optimizely/odp/lru_cache'
42
+ require_relative 'optimizely/odp/odp_manager'
43
+ require_relative 'optimizely/helpers/sdk_settings'
41
44
42
45
module Optimizely
43
46
class Project
@@ -46,7 +49,7 @@ class Project
46
49
attr_reader :notification_center
47
50
# @api no-doc
48
51
attr_reader :config_manager , :decision_service , :error_handler , :event_dispatcher ,
49
- :event_processor , :logger , :stopped
52
+ :event_processor , :logger , :odp_manager , : stopped
50
53
51
54
# Constructor for Projects.
52
55
#
@@ -62,6 +65,8 @@ class Project
62
65
# @param config_manager - Optional Responds to 'config' method.
63
66
# @param notification_center - Optional Instance of NotificationCenter.
64
67
# @param event_processor - Optional Responds to process.
68
+ # @param default_decide_options: Optional default decision options.
69
+ # @param settings: Optional instance of OptimizelySdkSettings for sdk configuration.
65
70
66
71
def initialize ( # rubocop:disable Metrics/ParameterLists
67
72
datafile = nil ,
@@ -74,13 +79,15 @@ def initialize( # rubocop:disable Metrics/ParameterLists
74
79
config_manager = nil ,
75
80
notification_center = nil ,
76
81
event_processor = nil ,
77
- default_decide_options = [ ]
82
+ default_decide_options = [ ] ,
83
+ settings = nil
78
84
)
79
85
@logger = logger || NoOpLogger . new
80
86
@error_handler = error_handler || NoOpErrorHandler . new
81
87
@event_dispatcher = event_dispatcher || EventDispatcher . new ( logger : @logger , error_handler : @error_handler )
82
88
@user_profile_service = user_profile_service
83
89
@default_decide_options = [ ]
90
+ @sdk_settings = settings
84
91
85
92
if default_decide_options . is_a? Array
86
93
@default_decide_options = default_decide_options . clone
@@ -98,6 +105,16 @@ def initialize( # rubocop:disable Metrics/ParameterLists
98
105
99
106
@notification_center = notification_center . is_a? ( Optimizely ::NotificationCenter ) ? notification_center : NotificationCenter . new ( @logger , @error_handler )
100
107
108
+ setup_odp!
109
+
110
+ @odp_manager = OdpManager . new (
111
+ disable : @sdk_settings . odp_disabled ,
112
+ segment_manager : @sdk_settings . odp_segment_manager ,
113
+ event_manager : @sdk_settings . odp_event_manager ,
114
+ segments_cache : @sdk_settings . odp_segments_cache ,
115
+ logger : @logger
116
+ )
117
+
101
118
@config_manager = if config_manager . respond_to? ( :config )
102
119
config_manager
103
120
elsif sdk_key
@@ -113,6 +130,10 @@ def initialize( # rubocop:disable Metrics/ParameterLists
113
130
StaticProjectConfigManager . new ( datafile , @logger , @error_handler , skip_json_validation )
114
131
end
115
132
133
+ # must call this even if it's scheduled as a listener
134
+ # in case the config manager was initialized before the listener was added
135
+ update_odp_config_on_datafile_update unless @sdk_settings . odp_disabled
136
+
116
137
@decision_service = DecisionService . new ( @logger , @user_profile_service )
117
138
118
139
@event_processor = if event_processor . respond_to? ( :process )
@@ -816,6 +837,7 @@ def close
816
837
@stopped = true
817
838
@config_manager . stop! if @config_manager . respond_to? ( :stop! )
818
839
@event_processor . stop! if @event_processor . respond_to? ( :stop! )
840
+ @odp_manager . stop!
819
841
end
820
842
821
843
def get_optimizely_config
@@ -869,6 +891,25 @@ def get_optimizely_config
869
891
end
870
892
end
871
893
894
+ # Send an event to the ODP server.
895
+ #
896
+ # @param action - the event action name.
897
+ # @param type - the event type (default = "fullstack").
898
+ # @param identifiers - a hash for identifiers.
899
+ # @param data - a hash for associated data. The default event data will be added to this data before sending to the ODP server.
900
+
901
+ def send_odp_event ( action :, type : Helpers ::Constants ::ODP_MANAGER_CONFIG [ :EVENT_TYPE ] , identifiers : { } , data : { } )
902
+ @odp_manager . send_event ( type : type , action : action , identifiers : identifiers , data : data )
903
+ end
904
+
905
+ def identify_user ( user_id :)
906
+ @odp_manager . identify_user ( user_id : user_id )
907
+ end
908
+
909
+ def fetch_qualified_segments ( user_id :, options : [ ] )
910
+ @odp_manager . fetch_qualified_segments ( user_id : user_id , options : options )
911
+ end
912
+
872
913
private
873
914
874
915
def get_variation_with_config ( experiment_key , user_id , attributes , config )
@@ -1126,5 +1167,51 @@ def send_impression(config, experiment, variation_key, flag_key, rule_key, enabl
1126
1167
def project_config
1127
1168
@config_manager . config
1128
1169
end
1170
+
1171
+ def update_odp_config_on_datafile_update
1172
+ # if datafile isn't ready, expects to be called again by the notification_center
1173
+ return if @config_manager . respond_to? ( :ready? ) && !@config_manager . ready?
1174
+
1175
+ config = @config_manager &.config
1176
+ return unless config
1177
+
1178
+ @odp_manager . update_odp_config ( config . public_key_for_odp , config . host_for_odp , config . all_segments )
1179
+ end
1180
+
1181
+ def setup_odp!
1182
+ unless @sdk_settings . is_a? Optimizely ::Helpers ::OptimizelySdkSettings
1183
+ @logger . log ( Logger ::DEBUG , 'Provided sdk_settings is not an OptimizelySdkSettings instance.' ) unless @sdk_settings . nil?
1184
+ @sdk_settings = Optimizely ::Helpers ::OptimizelySdkSettings . new
1185
+ end
1186
+
1187
+ return if @sdk_settings . odp_disabled
1188
+
1189
+ @notification_center . add_notification_listener (
1190
+ NotificationCenter ::NOTIFICATION_TYPES [ :OPTIMIZELY_CONFIG_UPDATE ] ,
1191
+ -> { update_odp_config_on_datafile_update }
1192
+ )
1193
+
1194
+ if !@sdk_settings . odp_segment_manager . nil? && !Helpers ::Validator . segment_manager_valid? ( @sdk_settings . odp_segment_manager )
1195
+ @logger . log ( Logger ::ERROR , 'Invalid ODP segment manager, reverting to default.' )
1196
+ @sdk_settings . odp_segment_manager = nil
1197
+ end
1198
+
1199
+ if !@sdk_settings . odp_event_manager . nil? && !Helpers ::Validator . event_manager_valid? ( @sdk_settings . odp_event_manager )
1200
+ @logger . log ( Logger ::ERROR , 'Invalid ODP event manager, reverting to default.' )
1201
+ @sdk_settings . odp_event_manager = nil
1202
+ end
1203
+
1204
+ return if @sdk_settings . odp_segment_manager
1205
+
1206
+ if !@sdk_settings . odp_segments_cache . nil? && !Helpers ::Validator . segments_cache_valid? ( @sdk_settings . odp_segments_cache )
1207
+ @logger . log ( Logger ::ERROR , 'Invalid ODP segments cache, reverting to default.' )
1208
+ @sdk_settings . odp_segments_cache = nil
1209
+ end
1210
+
1211
+ @sdk_settings . odp_segments_cache ||= LRUCache . new (
1212
+ @sdk_settings . segments_cache_size ,
1213
+ @sdk_settings . segments_cache_timeout_in_secs
1214
+ )
1215
+ end
1129
1216
end
1130
1217
end
0 commit comments