1111from splitio .optional .loaders import asyncio
1212
1313CONTROL = 'control'
14- EvaluationContext = namedtuple ('EvaluationContext' , ['flags' , 'segment_memberships' , 'segment_rbs_memberships' , 'segment_rbs_conditions' , 'excluded_rbs_segments ' ])
14+ EvaluationContext = namedtuple ('EvaluationContext' , ['flags' , 'segment_memberships' , 'rbs_segments ' ])
1515
1616_LOGGER = logging .getLogger (__name__ )
1717
@@ -115,59 +115,24 @@ def context_for(self, key, feature_names):
115115 :rtype: EvaluationContext
116116 """
117117 pending = set (feature_names )
118+ pending_rbs = set ()
118119 splits = {}
120+ rb_segments = {}
119121 pending_memberships = set ()
120- pending_rbs_memberships = set ()
121- while pending :
122+ while pending or pending_rbs :
122123 fetched = self ._flag_storage .fetch_many (list (pending ))
123- features = filter_missing (fetched )
124- splits .update (features )
125- pending = set ()
126- for feature in features .values ():
127- cf , cs , crbs = get_dependencies (feature )
128- for rbs in crbs :
129- rbs_cf , rbs_cs , rbs_crbs = get_dependencies (self ._rbs_segment_storage .get (rbs ))
130- cf .extend (rbs_cf )
131- cs .extend (rbs_cs )
132- crbs .extend (rbs_crbs )
133-
134- pending .update (filter (lambda f : f not in splits , cf ))
135- pending_memberships .update (cs )
136- pending_rbs_memberships .update (crbs )
137-
138- rbs_segment_memberships = {}
139- rbs_segment_conditions = {}
140- excluded_rbs_segments = set ()
141- key_membership = False
142- segment_memberhsip = False
143- for rbs_segment in pending_rbs_memberships :
144- rbs_segment_obj = self ._rbs_segment_storage .get (rbs_segment )
145- pending_memberships .update (rbs_segment_obj .get_condition_segment_names ())
146-
147- key_membership = key in rbs_segment_obj .excluded .get_excluded_keys ()
148- segment_memberhsip = False
149- for excluded_segment in rbs_segment_obj .excluded .get_excluded_segments ():
150- if excluded_segment .type == SegmentType .STANDARD and self ._segment_storage .segment_contains (excluded_segment .name , key ):
151- segment_memberhsip = True
152-
153- if excluded_segment .type == SegmentType .RULE_BASED :
154- rbs_segment = self ._rbs_segment_storage .get (excluded_segment .name )
155- if rbs_segment is not None :
156- excluded_rbs_segments .add (rbs_segment )
157-
158- rbs_segment_memberships .update ({rbs_segment : segment_memberhsip or key_membership })
159- if not (segment_memberhsip or key_membership ):
160- rbs_segment_conditions .update ({rbs_segment : [condition for condition in rbs_segment_obj .conditions ]})
161-
124+ fetched_rbs = self ._rbs_segment_storage .fetch_many (list (pending_rbs ))
125+ features , rbsegments , splits , rb_segments = update_objects (fetched , fetched_rbs , splits , rb_segments )
126+ pending , pending_memberships , pending_rbs = get_pending_objects (features , splits , rbsegments , rb_segments , pending_memberships )
127+
162128 return EvaluationContext (
163129 splits ,
164130 { segment : self ._segment_storage .segment_contains (segment , key )
165131 for segment in pending_memberships
166132 },
167- rbs_segment_memberships ,
168- rbs_segment_conditions ,
169- excluded_rbs_segments
133+ rb_segments
170134 )
135+
171136
172137class AsyncEvaluationDataFactory :
173138
@@ -186,72 +151,36 @@ async def context_for(self, key, feature_names):
186151 :rtype: EvaluationContext
187152 """
188153 pending = set (feature_names )
154+ pending_rbs = set ()
189155 splits = {}
156+ rb_segments = {}
190157 pending_memberships = set ()
191- pending_rbs_memberships = set ()
192- while pending :
158+ while pending or pending_rbs :
193159 fetched = await self ._flag_storage .fetch_many (list (pending ))
194- features = filter_missing (fetched )
195- splits .update (features )
196- pending = set ()
197- for feature in features .values ():
198- cf , cs , crbs = get_dependencies (feature )
199- for rbs in crbs :
200- rbs_cf , rbs_cs , rbs_crbs = get_dependencies (await self ._rbs_segment_storage .get (rbs ))
201- cf .extend (rbs_cf )
202- cs .extend (rbs_cs )
203- crbs .extend (rbs_crbs )
204-
205- pending .update (filter (lambda f : f not in splits , cf ))
206- pending_memberships .update (cs )
207- pending_rbs_memberships .update (crbs )
208-
209- rbs_segment_memberships = {}
210- rbs_segment_conditions = {}
211- excluded_rbs_segments = set ()
212- key_membership = False
213- segment_memberhsip = False
214- for rbs_segment in pending_rbs_memberships :
215- rbs_segment_obj = await self ._rbs_segment_storage .get (rbs_segment )
216- pending_memberships .update (rbs_segment_obj .get_condition_segment_names ())
217-
218- key_membership = key in rbs_segment_obj .excluded .get_excluded_keys ()
219- segment_memberhsip = False
220- for excluded_segment in rbs_segment_obj .excluded .get_excluded_segments ():
221- if excluded_segment .type == SegmentType .STANDARD and await self ._segment_storage .segment_contains (excluded_segment .name , key ):
222- segment_memberhsip = True
223-
224- if excluded_segment .type == SegmentType .RULE_BASED :
225- rbs_segment = await self ._rbs_segment_storage .get (excluded_segment .name )
226- if rbs_segment is not None :
227- excluded_rbs_segments .add (rbs_segment )
228-
229- rbs_segment_memberships .update ({rbs_segment : segment_memberhsip or key_membership })
230- if not (segment_memberhsip or key_membership ):
231- rbs_segment_conditions .update ({rbs_segment : [condition for condition in rbs_segment_obj .conditions ]})
160+ fetched_rbs = await self ._rbs_segment_storage .fetch_many (list (pending_rbs ))
161+ features , rbsegments , splits , rb_segments = update_objects (fetched , fetched_rbs , splits , rb_segments )
162+ pending , pending_memberships , pending_rbs = get_pending_objects (features , splits , rbsegments , rb_segments , pending_memberships )
232163
233164 segment_names = list (pending_memberships )
234165 segment_memberships = await asyncio .gather (* [
235166 self ._segment_storage .segment_contains (segment , key )
236167 for segment in segment_names
237168 ])
169+
238170 return EvaluationContext (
239171 splits ,
240172 dict (zip (segment_names , segment_memberships )),
241- rbs_segment_memberships ,
242- rbs_segment_conditions ,
243- excluded_rbs_segments
173+ rb_segments
244174 )
245175
246-
247- def get_dependencies (feature ):
176+ def get_dependencies (object ):
248177 """
249178 :rtype: tuple(list, list)
250179 """
251180 feature_names = []
252181 segment_names = []
253182 rbs_segment_names = []
254- for condition in feature .conditions :
183+ for condition in object .conditions :
255184 for matcher in condition .matchers :
256185 if isinstance (matcher ,RuleBasedSegmentMatcher ):
257186 rbs_segment_names .append (matcher ._rbs_segment_name )
@@ -264,3 +193,34 @@ def get_dependencies(feature):
264193
265194def filter_missing (features ):
266195 return {k : v for (k , v ) in features .items () if v is not None }
196+
197+ def get_pending_objects (features , splits , rbsegments , rb_segments , pending_memberships ):
198+ pending = set ()
199+ pending_rbs = set ()
200+ for feature in features .values ():
201+ cf , cs , crbs = get_dependencies (feature )
202+ pending .update (filter (lambda f : f not in splits , cf ))
203+ pending_memberships .update (cs )
204+ pending_rbs .update (filter (lambda f : f not in rb_segments , crbs ))
205+
206+ for rb_segment in rbsegments .values ():
207+ cf , cs , crbs = get_dependencies (rb_segment )
208+ pending .update (filter (lambda f : f not in splits , cf ))
209+ pending_memberships .update (cs )
210+ for excluded_segment in rb_segment .excluded .get_excluded_segments ():
211+ if excluded_segment .type == SegmentType .STANDARD :
212+ pending_memberships .add (excluded_segment .name )
213+ else :
214+ pending_rbs .update (filter (lambda f : f not in rb_segments , [excluded_segment .name ]))
215+ pending_rbs .update (filter (lambda f : f not in rb_segments , crbs ))
216+
217+ return pending , pending_memberships , pending_rbs
218+
219+ def update_objects (fetched , fetched_rbs , splits , rb_segments ):
220+ features = filter_missing (fetched )
221+ rbsegments = filter_missing (fetched_rbs )
222+ splits .update (features )
223+ rb_segments .update (rbsegments )
224+
225+ return features , rbsegments , splits , rb_segments
226+
0 commit comments