1- # Copyright 2016-2017, 2019-2020 Optimizely
1+ # Copyright 2016-2017, 2019-2021 Optimizely
22# Licensed under the Apache License, Version 2.0 (the "License");
33# you may not use this file except in compliance with the License.
44# You may obtain a copy of the License at
@@ -71,13 +71,13 @@ def find_bucket(self, project_config, bucketing_id, parent_id, traffic_allocatio
7171 traffic_allocations: Traffic allocations representing traffic allotted to experiments or variations.
7272
7373 Returns:
74- Entity ID which may represent experiment or variation.
74+ Entity ID which may represent experiment or variation and
7575 """
76-
7776 bucketing_key = BUCKETING_ID_TEMPLATE .format (bucketing_id = bucketing_id , parent_id = parent_id )
7877 bucketing_number = self ._generate_bucket_value (bucketing_key )
78+ message = 'Assigned bucket %s to user with bucketing ID "%s".' % (bucketing_number , bucketing_id )
7979 project_config .logger .debug (
80- 'Assigned bucket %s to user with bucketing ID "%s".' % ( bucketing_number , bucketing_id )
80+ message
8181 )
8282
8383 for traffic_allocation in traffic_allocations :
@@ -97,41 +97,57 @@ def bucket(self, project_config, experiment, user_id, bucketing_id):
9797 bucketing_id: ID to be used for bucketing the user.
9898
9999 Returns:
100- Variation in which user with ID user_id will be put in. None if no variation.
100+ Variation in which user with ID user_id will be put in. None if no variation
101+ and array of log messages representing decision making.
102+ */.
101103 """
102-
104+ decide_reasons = []
103105 if not experiment :
104- return None
106+ return None , decide_reasons
105107
106108 # Determine if experiment is in a mutually exclusive group.
107109 # This will not affect evaluation of rollout rules.
108110 if experiment .groupPolicy in GROUP_POLICIES :
109111 group = project_config .get_group (experiment .groupId )
110112
111113 if not group :
112- return None
114+ return None , decide_reasons
113115
114116 user_experiment_id = self .find_bucket (
115117 project_config , bucketing_id , experiment .groupId , group .trafficAllocation ,
116118 )
119+
117120 if not user_experiment_id :
118- project_config .logger .info ('User "%s" is in no experiment.' % user_id )
119- return None
121+ message = 'User "%s" is in no experiment.' % user_id
122+ project_config .logger .info (message )
123+ decide_reasons .append (message )
124+ return None , decide_reasons
120125
121126 if user_experiment_id != experiment .id :
127+ message = 'User "%s" is not in experiment "%s" of group %s.' \
128+ % (user_id , experiment .key , experiment .groupId )
122129 project_config .logger .info (
123- 'User "%s" is not in experiment "%s" of group %s.' % ( user_id , experiment . key , experiment . groupId )
130+ message
124131 )
125- return None
132+ decide_reasons .append (message )
133+ return None , decide_reasons
126134
135+ message = 'User "%s" is in experiment %s of group %s.' % (user_id , experiment .key , experiment .groupId )
127136 project_config .logger .info (
128- 'User "%s" is in experiment %s of group %s.' % ( user_id , experiment . key , experiment . groupId )
137+ message
129138 )
139+ decide_reasons .append (message )
130140
131141 # Bucket user if not in white-list and in group (if any)
132- variation_id = self .find_bucket (project_config , bucketing_id , experiment .id , experiment .trafficAllocation )
142+ variation_id = self .find_bucket (project_config , bucketing_id ,
143+ experiment .id , experiment .trafficAllocation )
133144 if variation_id :
134145 variation = project_config .get_variation_from_id (experiment .key , variation_id )
135- return variation
146+ return variation , decide_reasons
136147
137- return None
148+ else :
149+ message = 'Bucketed into an empty traffic range. Returning nil.'
150+ project_config .logger .info (message )
151+ decide_reasons .append (message )
152+
153+ return None , decide_reasons
0 commit comments