Skip to content

Commit 1aa9961

Browse files
committed
Moving log messages from bucketer to decision_service
1 parent 9e09ff4 commit 1aa9961

File tree

3 files changed

+32
-42
lines changed

3 files changed

+32
-42
lines changed

Diff for: optimizely/bucketer.py

+28-31
Original file line numberDiff line numberDiff line change
@@ -38,41 +38,41 @@ def __init__(self):
3838
def _generate_unsigned_hash_code_32_bit(self, bucketing_id):
3939
""" Helper method to retrieve hash code.
4040
41-
Args:
42-
bucketing_id: ID for bucketing.
41+
Args:
42+
bucketing_id: ID for bucketing.
4343
44-
Returns:
45-
Hash code which is a 32 bit unsigned integer.
46-
"""
44+
Returns:
45+
Hash code which is a 32 bit unsigned integer.
46+
"""
4747

4848
# Adjusting MurmurHash code to be unsigned
4949
return mmh3.hash(bucketing_id, self.bucket_seed) & UNSIGNED_MAX_32_BIT_VALUE
5050

5151
def _generate_bucket_value(self, bucketing_id):
5252
""" Helper function to generate bucket value in half-closed interval [0, MAX_TRAFFIC_VALUE).
5353
54-
Args:
55-
bucketing_id: ID for bucketing.
54+
Args:
55+
bucketing_id: ID for bucketing.
5656
57-
Returns:
58-
Bucket value corresponding to the provided bucketing ID.
59-
"""
57+
Returns:
58+
Bucket value corresponding to the provided bucketing ID.
59+
"""
6060

6161
ratio = float(self._generate_unsigned_hash_code_32_bit(bucketing_id)) / MAX_HASH_VALUE
6262
return math.floor(ratio * MAX_TRAFFIC_VALUE)
6363

6464
def find_bucket(self, project_config, bucketing_id, parent_id, traffic_allocations):
6565
""" Determine entity based on bucket value and traffic allocations.
6666
67-
Args:
68-
project_config: Instance of ProjectConfig.
69-
bucketing_id: ID to be used for bucketing the user.
70-
parent_id: ID representing group or experiment.
71-
traffic_allocations: Traffic allocations representing traffic allotted to experiments or variations.
67+
Args:
68+
project_config: Instance of ProjectConfig.
69+
bucketing_id: ID to be used for bucketing the user.
70+
parent_id: ID representing group or experiment.
71+
traffic_allocations: Traffic allocations representing traffic allotted to experiments or variations.
7272
73-
Returns:
74-
Entity ID which may represent experiment or variation.
75-
"""
73+
Returns:
74+
Entity ID which may represent experiment or variation.
75+
"""
7676

7777
bucketing_key = BUCKETING_ID_TEMPLATE.format(bucketing_id=bucketing_id, parent_id=parent_id)
7878
bucketing_number = self._generate_bucket_value(bucketing_key)
@@ -90,20 +90,21 @@ def find_bucket(self, project_config, bucketing_id, parent_id, traffic_allocatio
9090
def bucket(self, project_config, experiment, user_id, bucketing_id):
9191
""" For a given experiment and bucketing ID determines variation to be shown to user.
9292
93-
Args:
94-
project_config: Instance of ProjectConfig.
95-
experiment: Object representing the experiment for which user is to be bucketed.
96-
user_id: ID for user.
97-
bucketing_id: ID to be used for bucketing the user.
93+
Args:
94+
project_config: Instance of ProjectConfig.
95+
experiment: Object representing the experiment or rollout rule in which user is to be bucketed.
96+
user_id: ID for user.
97+
bucketing_id: ID to be used for bucketing the user.
9898
99-
Returns:
100-
Variation in which user with ID user_id will be put in. None if no variation.
101-
"""
99+
Returns:
100+
Variation in which user with ID user_id will be put in. None if no variation.
101+
"""
102102

103103
if not experiment:
104104
return None
105105

106-
# Determine if experiment is in a mutually exclusive group
106+
# Determine if experiment is in a mutually exclusive group.
107+
# This will not affect evaluation of rollout rules.
107108
if experiment.groupPolicy in GROUP_POLICIES:
108109
group = project_config.get_group(experiment.groupId)
109110

@@ -131,10 +132,6 @@ def bucket(self, project_config, experiment, user_id, bucketing_id):
131132
variation_id = self.find_bucket(project_config, bucketing_id, experiment.id, experiment.trafficAllocation)
132133
if variation_id:
133134
variation = project_config.get_variation_from_id(experiment.key, variation_id)
134-
project_config.logger.info(
135-
'User "%s" is in variation "%s" of experiment %s.' % (user_id, variation.key, experiment.key)
136-
)
137135
return variation
138136

139-
project_config.logger.info('User "%s" is in no variation.' % user_id)
140137
return None

Diff for: optimizely/decision_service.py

+4
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ def get_variation(self, project_config, experiment, user_id, attributes, ignore_
274274
variation = self.bucketer.bucket(project_config, experiment, user_id, bucketing_id)
275275

276276
if variation:
277+
self.logger.info(
278+
'User "%s" is in variation "%s" of experiment %s.' % (user_id, variation.key, experiment.key)
279+
)
277280
# Store this new decision and return the variation for the user
278281
if not ignore_user_profile and self.user_profile_service:
279282
try:
@@ -283,6 +286,7 @@ def get_variation(self, project_config, experiment, user_id, attributes, ignore_
283286
self.logger.exception('Unable to save user profile for user "{}".'.format(user_id))
284287
return variation
285288

289+
self.logger.info('User "%s" is in no variation.' % user_id)
286290
return None
287291

288292
def get_variation_for_rollout(self, project_config, rollout, user_id, attributes=None):

Diff for: tests/test_bucketing.py

-11
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,6 @@ def test_bucket(self):
234234
)
235235

236236
mock_config_logging.debug.assert_called_once_with('Assigned bucket 42 to user with bucketing ID "test_user".')
237-
mock_config_logging.info.assert_called_once_with(
238-
'User "test_user" is in variation "control" of experiment test_experiment.'
239-
)
240237

241238
# Empty entity ID
242239
with mock.patch('optimizely.bucketer.Bucketer._generate_bucket_value', return_value=4242), mock.patch.object(
@@ -252,7 +249,6 @@ def test_bucket(self):
252249
)
253250

254251
mock_config_logging.debug.assert_called_once_with('Assigned bucket 4242 to user with bucketing ID "test_user".')
255-
mock_config_logging.info.assert_called_once_with('User "test_user" is in no variation.')
256252

257253
# Variation 2
258254
with mock.patch('optimizely.bucketer.Bucketer._generate_bucket_value', return_value=5042), mock.patch.object(
@@ -269,9 +265,6 @@ def test_bucket(self):
269265
)
270266

271267
mock_config_logging.debug.assert_called_once_with('Assigned bucket 5042 to user with bucketing ID "test_user".')
272-
mock_config_logging.info.assert_called_once_with(
273-
'User "test_user" is in variation "variation" of experiment test_experiment.'
274-
)
275268

276269
# No matching variation
277270
with mock.patch('optimizely.bucketer.Bucketer._generate_bucket_value', return_value=424242), mock.patch.object(
@@ -289,7 +282,6 @@ def test_bucket(self):
289282
mock_config_logging.debug.assert_called_once_with(
290283
'Assigned bucket 424242 to user with bucketing ID "test_user".'
291284
)
292-
mock_config_logging.info.assert_called_once_with('User "test_user" is in no variation.')
293285

294286
def test_bucket__experiment_in_group(self):
295287
""" Test that for provided bucket values correct variation ID is returned. """
@@ -316,7 +308,6 @@ def test_bucket__experiment_in_group(self):
316308
mock_config_logging.info.assert_has_calls(
317309
[
318310
mock.call('User "test_user" is in experiment group_exp_1 of group 19228.'),
319-
mock.call('User "test_user" is in variation "group_exp_1_variation" of experiment group_exp_1.'),
320311
]
321312
)
322313

@@ -356,7 +347,6 @@ def test_bucket__experiment_in_group(self):
356347
mock_config_logging.info.assert_has_calls(
357348
[
358349
mock.call('User "test_user" is in experiment group_exp_1 of group 19228.'),
359-
mock.call('User "test_user" is in no variation.'),
360350
]
361351
)
362352

@@ -399,6 +389,5 @@ def test_bucket__experiment_in_group(self):
399389
mock_config_logging.info.assert_has_calls(
400390
[
401391
mock.call('User "test_user" is in experiment group_exp_1 of group 19228.'),
402-
mock.call('User "test_user" is in no variation.'),
403392
]
404393
)

0 commit comments

Comments
 (0)