@@ -57,7 +57,7 @@ def initialize(datafile, event_dispatcher = nil, logger = nil, error_handler = n
5757 @event_dispatcher = event_dispatcher || EventDispatcher . new
5858
5959 begin
60- validate_inputs ( datafile , skip_json_validation )
60+ validate_instantiation_options ( datafile , skip_json_validation )
6161 rescue InvalidInputError => e
6262 @is_valid = false
6363 logger = SimpleLogger . new
@@ -82,7 +82,7 @@ def initialize(datafile, event_dispatcher = nil, logger = nil, error_handler = n
8282 end
8383
8484 @bucketer = Bucketer . new ( @config )
85- @event_builder = EVENT_BUILDERS_BY_VERSION [ @config . version ] . new ( @config , @bucketer )
85+ @event_builder = EVENT_BUILDERS_BY_VERSION [ @config . version ] . new ( @config )
8686 end
8787
8888 def activate ( experiment_key , user_id , attributes = nil )
@@ -101,24 +101,15 @@ def activate(experiment_key, user_id, attributes = nil)
101101 return nil
102102 end
103103
104- if attributes && !attributes_valid? ( attributes )
105- @logger . log ( Logger ::INFO , "Not activating user '#{ user_id } '." )
106- return nil
107- end
108-
109- unless preconditions_valid? ( experiment_key , user_id , attributes )
110- @logger . log ( Logger ::INFO , "Not activating user '#{ user_id } '." )
111- return nil
112- end
113-
114- variation_id = @bucketer . bucket ( experiment_key , user_id )
104+ variation_key = get_variation ( experiment_key , user_id , attributes )
115105
116- if not variation_id
106+ if variation_key . nil?
117107 @logger . log ( Logger ::INFO , "Not activating user '#{ user_id } '." )
118108 return nil
119109 end
120110
121111 # Create and dispatch impression event
112+ variation_id = @config . get_variation_id_from_key ( experiment_key , variation_key )
122113 impression_event = @event_builder . create_impression_event ( experiment_key , variation_id , user_id , attributes )
123114 @logger . log ( Logger ::INFO ,
124115 'Dispatching impression event to URL %s with params %s.' % [ impression_event . url ,
@@ -129,7 +120,7 @@ def activate(experiment_key, user_id, attributes = nil)
129120 @logger . log ( Logger ::ERROR , "Unable to dispatch impression event. Error: #{ e } " )
130121 end
131122
132- @config . get_variation_key_from_id ( experiment_key , variation_id )
123+ variation_key
133124 end
134125
135126 def get_variation ( experiment_key , user_id , attributes = nil )
@@ -148,24 +139,34 @@ def get_variation(experiment_key, user_id, attributes = nil)
148139 return nil
149140 end
150141
151- if attributes && ! attributes_valid? ( attributes )
142+ unless preconditions_valid? ( experiment_key , attributes )
152143 @logger . log ( Logger ::INFO , "Not activating user '#{ user_id } ." )
153144 return nil
154145 end
155146
156- unless preconditions_valid? ( experiment_key , user_id , attributes )
157- @logger . log ( Logger ::INFO , "Not activating user '#{ user_id } ." )
147+ variation_id = @bucketer . get_forced_variation_id ( experiment_key , user_id )
148+
149+ unless variation_id . nil?
150+ return @config . get_variation_key_from_id ( experiment_key , variation_id )
151+ end
152+
153+ unless Audience . user_in_experiment? ( @config , experiment_key , attributes )
154+ @logger . log ( Logger ::INFO ,
155+ "User '#{ user_id } ' does not meet the conditions to be in experiment '#{ experiment_key } '." )
158156 return nil
159157 end
160158
161159 variation_id = @bucketer . bucket ( experiment_key , user_id )
162- @config . get_variation_key_from_id ( experiment_key , variation_id )
160+ unless variation_id . nil?
161+ return @config . get_variation_key_from_id ( experiment_key , variation_id )
162+ end
163+ nil
163164 end
164165
165166 def track ( event_key , user_id , attributes = nil , event_tags = nil )
166167 # Send conversion event to Optimizely.
167168 #
168- # event_key - Goal key representing the event which needs to be recorded.
169+ # event_key - Event key representing the event which needs to be recorded.
169170 # user_id - String ID for user.
170171 # attributes - Hash representing visitor attributes and values which need to be recorded.
171172 # event_tags - Hash representing metadata associated with the event.
@@ -183,34 +184,26 @@ def track(event_key, user_id, attributes = nil, event_tags = nil)
183184 @logger . log ( Logger ::WARN , 'Event value is deprecated in track call. Use event tags to pass in revenue value instead.' )
184185 end
185186
186- return nil if attributes && !attributes_valid? ( attributes )
187- return nil if event_tags && !event_tags_valid? ( event_tags )
187+ return nil unless user_inputs_valid? ( attributes , event_tags )
188188
189- experiment_ids = @config . get_experiment_ids_for_goal ( event_key )
189+ experiment_ids = @config . get_experiment_ids_for_event ( event_key )
190190 if experiment_ids . empty?
191191 @config . logger . log ( Logger ::INFO , "Not tracking user '#{ user_id } '." )
192192 return nil
193193 end
194194
195195 # Filter out experiments that are not running or that do not include the user in audience conditions
196- valid_experiment_keys = [ ]
197- experiment_ids . each do |experiment_id |
198- experiment_key = @config . experiment_id_map [ experiment_id ] [ 'key' ]
199- unless preconditions_valid? ( experiment_key , user_id , attributes )
200- @config . logger . log ( Logger ::INFO , "Not tracking user '#{ user_id } ' for experiment '#{ experiment_key } '." )
201- next
202- end
203- valid_experiment_keys . push ( experiment_key )
204- end
196+
197+ experiment_variation_map = get_valid_experiments_for_event ( event_key , user_id , attributes )
205198
206199 # Don't track events without valid experiments attached
207- if valid_experiment_keys . empty?
200+ if experiment_variation_map . empty?
208201 @logger . log ( Logger ::INFO , "There are no valid experiments for event '#{ event_key } ' to track." )
209202 return nil
210203 end
211204
212205 conversion_event = @event_builder . create_conversion_event ( event_key , user_id , attributes ,
213- event_tags , valid_experiment_keys )
206+ event_tags , experiment_variation_map )
214207 @logger . log ( Logger ::INFO ,
215208 'Dispatching conversion event to URL %s with params %s.' % [ conversion_event . url ,
216209 conversion_event . params ] )
@@ -223,7 +216,35 @@ def track(event_key, user_id, attributes = nil, event_tags = nil)
223216
224217 private
225218
226- def preconditions_valid? ( experiment_key , user_id , attributes )
219+ def get_valid_experiments_for_event ( event_key , user_id , attributes )
220+ # Get the experiments that we should be tracking for the given event.
221+ #
222+ # event_key - Event key representing the event which needs to be recorded.
223+ # user_id - String ID for user.
224+ # attributes - Map of attributes of the user.
225+ #
226+ # Returns Map where each object contains the ID of the experiment to track and the ID of the variation the user
227+ # is bucketed into.
228+
229+ valid_experiments = { }
230+ experiment_ids = @config . get_experiment_ids_for_event ( event_key )
231+ experiment_ids . each do |experiment_id |
232+ experiment_key = @config . get_experiment_key ( experiment_id )
233+ variation_key = get_variation ( experiment_key , user_id , attributes )
234+
235+ if variation_key . nil?
236+ @logger . log ( Logger ::INFO , "Not tracking user '#{ user_id } ' for experiment '#{ experiment_key } '." )
237+ next
238+ end
239+
240+ variation_id = @config . get_variation_id_from_key ( experiment_key , variation_key )
241+ valid_experiments [ experiment_id ] = variation_id
242+ end
243+
244+ valid_experiments
245+ end
246+
247+ def preconditions_valid? ( experiment_key , attributes = nil , event_tags = nil )
227248 # Validates preconditions for bucketing a user.
228249 #
229250 # experiment_key - String key for an experiment.
@@ -232,18 +253,29 @@ def preconditions_valid?(experiment_key, user_id, attributes)
232253 #
233254 # Returns boolean representing whether all preconditions are valid.
234255
256+ return false unless user_inputs_valid? ( attributes , event_tags )
257+
235258 unless @config . experiment_running? ( experiment_key )
236259 @logger . log ( Logger ::INFO , "Experiment '#{ experiment_key } ' is not running." )
237260 return false
238261 end
239262
240- if @config . user_in_forced_variation? ( experiment_key , user_id )
241- return true
263+ true
264+ end
265+
266+ def user_inputs_valid? ( attributes = nil , event_tags = nil )
267+ # Helper method to validate user inputs.
268+ #
269+ # attributes - Dict representing user attributes.
270+ # event_tags - Dict representing metadata associated with an event.
271+ #
272+ # Returns boolean True if inputs are valid. False otherwise.
273+
274+ if !attributes . nil? && !attributes_valid? ( attributes )
275+ return false
242276 end
243277
244- unless Audience . user_in_experiment? ( @config , experiment_key , attributes )
245- @logger . log ( Logger ::INFO ,
246- "User '#{ user_id } ' does not meet the conditions to be in experiment '#{ experiment_key } '." )
278+ if !event_tags . nil? && !event_tags_valid? ( event_tags )
247279 return false
248280 end
249281
@@ -268,7 +300,7 @@ def event_tags_valid?(event_tags)
268300 true
269301 end
270302
271- def validate_inputs ( datafile , skip_json_validation )
303+ def validate_instantiation_options ( datafile , skip_json_validation )
272304 unless skip_json_validation
273305 raise InvalidInputError . new ( 'datafile' ) unless Helpers ::Validator . datafile_valid? ( datafile )
274306 end
0 commit comments