1- import base64
21import json
32import re
4- from typing import Callable , Iterable , Optional
3+ from typing import Callable , Optional
54
65from fbclient .common_types import FBEvent , FBUser , _EvalResult
76from fbclient .event_types import FlagEventVariation
6766
6867__NOT_IN_SEGMENT_CLAUSE__ = 'User is not in segment'
6968
69+ __EXPT_KEY_PREFIX__ = "expt"
70+
7071
7172class Evaluator :
7273 def __init__ (self ,
@@ -127,23 +128,19 @@ def _match_condition_user_variation(self, flag: dict, user: FBUser) -> Optional[
127128 for rule in flag ['rules' ]:
128129 if self ._match_any_rule (user , rule ):
129130 return self ._get_rollout_variation_option (flag ,
130- rule [ 'variations' ] ,
131+ rule ,
131132 user ,
132133 REASON_RULE_MATCH ,
133- flag ['exptIncludeAllTargets' ],
134- rule ['includedInExpt' ],
135134 flag ['key' ],
136135 flag ['name' ])
137136 return None
138137
139138 # get value from default rule
140139 def _match_default_user_variation (self , flag : dict , user : FBUser ) -> Optional [_EvalResult ]:
141140 return self ._get_rollout_variation_option (flag ,
142- flag ['fallthrough' ][ 'variations' ] ,
141+ flag ['fallthrough' ],
143142 user ,
144143 REASON_FALLTHROUGH ,
145- flag ['exptIncludeAllTargets' ],
146- flag ['fallthrough' ]['includedInExpt' ],
147144 flag ['key' ],
148145 flag ['name' ])
149146
@@ -264,15 +261,13 @@ def match_segment(user: FBUser, segment: Optional[dict]) -> bool:
264261
265262 def _get_rollout_variation_option (self ,
266263 flag : dict ,
267- rollouts : Iterable [ dict ] ,
264+ rollout_variations : dict ,
268265 user : FBUser ,
269266 reason : str ,
270- expt_include_all_targets : bool ,
271- rule_inclued_in_expt : bool ,
272267 key_name : str ,
273268 name : str ) -> Optional [_EvalResult ]:
274269
275- def is_send_to_expt (user_key : str ,
270+ def is_send_to_expt (dispatch_key : str ,
276271 rollout : dict ,
277272 expt_include_all_targets : bool ,
278273 rule_inclued_in_expt : bool ) -> bool :
@@ -288,14 +283,16 @@ def is_send_to_expt(user_key: str,
288283 upper_bound = send_to_expt_percentage / splitting_percentage
289284 if upper_bound > 1 :
290285 upper_bound = 1
291- new_user_key = base64 . b64encode ( user_key . encode ()). decode ( )
292- return VariationSplittingAlgorithm (new_user_key , [0 , upper_bound ]).is_key_belongs_to_percentage ()
286+ new_dispatch_key = "" . join (( __EXPT_KEY_PREFIX__ , dispatch_key ) )
287+ return VariationSplittingAlgorithm (new_dispatch_key , [0 , upper_bound ]).is_key_belongs_to_percentage ()
293288 return False
294289
295- user_key = user .get ('keyid' )
296- for rollout in rollouts :
297- if VariationSplittingAlgorithm (user_key , rollout ['rollout' ]).is_key_belongs_to_percentage (): # type: ignore
298- send_to_expt = is_send_to_expt (user_key , rollout , expt_include_all_targets , rule_inclued_in_expt ) # type: ignore
290+ dispatch_key = rollout_variations .get ('dispatchKey' )
291+ dispatch_key = dispatch_key if dispatch_key else 'keyid'
292+ dispatch_key_value = "" .join ((flag ['key' ], user .get (dispatch_key , "" ))) # type: ignore
293+ for rollout in rollout_variations ['variations' ]:
294+ if VariationSplittingAlgorithm (dispatch_key_value , rollout ['rollout' ]).is_key_belongs_to_percentage (): # type: ignore
295+ send_to_expt = is_send_to_expt (dispatch_key_value , rollout , flag ['exptIncludeAllTargets' ], rollout_variations ['includedInExpt' ]) # type: ignore
299296 return _EvalResult (rollout ['id' ],
300297 flag ['variationMap' ][rollout ['id' ]],
301298 reason ,
0 commit comments