88from splitio .models .impressions import Impression
99from splitio .models .telemetry import MethodExceptions , MethodLatencies , TelemetryConfig , MAX_TAGS , get_latency_bucket_index
1010from splitio .storage import SplitStorage , SegmentStorage , ImpressionStorage , EventStorage , TelemetryStorage
11+ from splitio .util .storage_helper import get_valid_flag_sets , combine_valid_flag_sets
1112
1213_LOGGER = logging .getLogger (__name__ )
1314
1415class PluggableSplitStorage (SplitStorage ):
15- """InMemory implementation of a split storage."""
16+ """InMemory implementation of feature flag storage."""
1617
17- _SPLIT_NAME_LENGTH = 12
18+ _FEATURE_FLAG_NAME_LENGTH = 19
1819
19- def __init__ (self , pluggable_adapter , prefix = None ):
20+ def __init__ (self , pluggable_adapter , prefix = None , config_flag_sets = [] ):
2021 """
2122 Class constructor.
2223
@@ -26,51 +27,78 @@ def __init__(self, pluggable_adapter, prefix=None):
2627 :type prefix: str
2728 """
2829 self ._pluggable_adapter = pluggable_adapter
29- self ._prefix = "SPLITIO.split.{split_name}"
30+ self ._config_flag_sets = config_flag_sets
31+ self ._prefix = "SPLITIO.split.{feature_flag_name}"
3032 self ._traffic_type_prefix = "SPLITIO.trafficType.{traffic_type_name}"
31- self ._split_till_prefix = "SPLITIO.splits.till"
33+ self ._feature_flag_till_prefix = "SPLITIO.splits.till"
34+ self ._feature_flag_set_prefix = 'SPLITIO.set.{flag_set}'
3235 if prefix is not None :
3336 self ._prefix = prefix + "." + self ._prefix
3437 self ._traffic_type_prefix = prefix + "." + self ._traffic_type_prefix
35- self ._split_till_prefix = prefix + "." + self ._split_till_prefix
38+ self ._feature_flag_till_prefix = prefix + "." + self ._feature_flag_till_prefix
39+ self ._feature_flag_set_prefix = prefix + "." + self ._feature_flag_till_prefix
3640
37- def get (self , split_name ):
41+ def get (self , feature_flag_name ):
3842 """
39- Retrieve a split .
43+ Retrieve a feature flag .
4044
41- :param split_name : Name of the feature to fetch.
42- :type split_name : str
45+ :param feature_flag_name : Name of the feature to fetch.
46+ :type feature_flag_name : str
4347
4448 :rtype: splitio.models.splits.Split
4549 """
4650 try :
47- split = self ._pluggable_adapter .get (self ._prefix .format (split_name = split_name ))
48- if not split :
51+ feature_flag = self ._pluggable_adapter .get (self ._prefix .format (feature_flag_name = feature_flag_name ))
52+ if not feature_flag :
4953 return None
50- return splits .from_raw (split )
54+ return splits .from_raw (feature_flag )
5155 except Exception :
52- _LOGGER .error ('Error getting split from storage' )
56+ _LOGGER .error ('Error getting feature flag from storage' )
5357 _LOGGER .debug ('Error: ' , exc_info = True )
5458 return None
5559
56- def fetch_many (self , split_names ):
60+ def fetch_many (self , feature_flag_names ):
5761 """
58- Retrieve splits .
62+ Retrieve feature flags .
5963
60- :param split_names : Names of the features to fetch.
61- :type split_name : list(str)
64+ :param feature_flag_names : Names of the features to fetch.
65+ :type feature_flag_name : list(str)
6266
6367 :return: A dict with split objects parsed from queue.
6468 :rtype: dict(split_name, splitio.models.splits.Split)
6569 """
6670 try :
67- prefix_added = [self ._prefix .format (split_name = split_name ) for split_name in split_names ]
68- return {split ['name' ]: splits .from_raw (split ) for split in self ._pluggable_adapter .get_many (prefix_added )}
71+ prefix_added = [self ._prefix .format (feature_flag_name = feature_flag_name ) for feature_flag_name in feature_flag_names ]
72+ return {feature_flag ['name' ]: splits .from_raw (feature_flag ) for feature_flag in self ._pluggable_adapter .get_many (prefix_added )}
6973 except Exception :
70- _LOGGER .error ('Error getting split from storage' )
74+ _LOGGER .error ('Error getting feature flag from storage' )
7175 _LOGGER .debug ('Error: ' , exc_info = True )
7276 return None
7377
78+ def get_feature_flags_by_sets (self , flag_sets ):
79+ """
80+ Retrieve feature flags by flag set.
81+
82+ :param flag_set: Names of the flag set to fetch.
83+ :type flag_set: str
84+
85+ :return: Feature flag names that are tagged with the flag set
86+ :rtype: listt(str)
87+ """
88+ try :
89+ sets_to_fetch = get_valid_flag_sets (flag_sets , self ._config_flag_sets )
90+ if sets_to_fetch == []:
91+ return []
92+
93+ keys = [self ._prefix (feature_flag_name ) for feature_flag_name in sets_to_fetch ]
94+ result_sets = self ._pluggable_adapter .get_many (keys )
95+ return list (combine_valid_flag_sets (result_sets ))
96+ except Exception :
97+ _LOGGER .error ('Error fetching feature flag from storage' )
98+ _LOGGER .debug ('Error: ' , exc_info = True )
99+ return None
100+
101+
74102 # TODO: To be added when producer mode is supported
75103# def put_many(self, splits, change_number):
76104# """
@@ -127,14 +155,14 @@ def update(self, to_add, to_delete, new_change_number):
127155
128156 def get_change_number (self ):
129157 """
130- Retrieve latest split change number.
158+ Retrieve latest feature flag change number.
131159
132160 :rtype: int
133161 """
134162 try :
135- return self ._pluggable_adapter .get (self ._split_till_prefix )
163+ return self ._pluggable_adapter .get (self ._feature_flag_till_prefix )
136164 except Exception :
137- _LOGGER .error ('Error getting change number in split storage' )
165+ _LOGGER .error ('Error getting change number in feature flag storage' )
138166 _LOGGER .debug ('Error: ' , exc_info = True )
139167 return None
140168
@@ -156,35 +184,35 @@ def get_change_number(self):
156184
157185 def get_split_names (self ):
158186 """
159- Retrieve a list of all split names.
187+ Retrieve a list of all feature flag names.
160188
161- :return: List of split names.
189+ :return: List of feature flag names.
162190 :rtype: list(str)
163191 """
164192 try :
165- return [split .name for split in self .get_all ()]
193+ return [feature_flag .name for feature_flag in self .get_all ()]
166194 except Exception :
167- _LOGGER .error ('Error getting split names from storage' )
195+ _LOGGER .error ('Error getting feature flag names from storage' )
168196 _LOGGER .debug ('Error: ' , exc_info = True )
169197 return None
170198
171199 def get_all (self ):
172200 """
173- Return all the splits .
201+ Return all the feature flags .
174202
175- :return: List of all the splits .
203+ :return: List of all the feature flags .
176204 :rtype: list
177205 """
178206 try :
179- return [splits .from_raw (self ._pluggable_adapter .get (key )) for key in self ._pluggable_adapter .get_keys_by_prefix (self ._prefix [:- self ._SPLIT_NAME_LENGTH ])]
207+ return [splits .from_raw (self ._pluggable_adapter .get (key )) for key in self ._pluggable_adapter .get_keys_by_prefix (self ._prefix [:- self ._FEATURE_FLAG_NAME_LENGTH ])]
180208 except Exception :
181- _LOGGER .error ('Error getting split keys from storage' )
209+ _LOGGER .error ('Error getting feature flag keys from storage' )
182210 _LOGGER .debug ('Error: ' , exc_info = True )
183211 return None
184212
185213 def traffic_type_exists (self , traffic_type_name ):
186214 """
187- Return whether the traffic type exists in at least one split in cache.
215+ Return whether the traffic type exists in at least one feature flag in cache.
188216
189217 :param traffic_type_name: Traffic type to validate.
190218 :type traffic_type_name: str
@@ -195,7 +223,7 @@ def traffic_type_exists(self, traffic_type_name):
195223 try :
196224 return self ._pluggable_adapter .get (self ._traffic_type_prefix .format (traffic_type_name = traffic_type_name )) != None
197225 except Exception :
198- _LOGGER .error ('Error getting split info from storage' )
226+ _LOGGER .error ('Error getting traffic type info from storage' )
199227 _LOGGER .debug ('Error: ' , exc_info = True )
200228 return None
201229
@@ -264,21 +292,21 @@ def kill_locally(self, split_name, default_treatment, change_number):
264292
265293 def get_all_splits (self ):
266294 """
267- Return all the splits .
295+ Return all the feature flags .
268296
269- :return: List of all the splits .
297+ :return: List of all the feature flags .
270298 :rtype: list
271299 """
272300 try :
273301 return self .get_all ()
274302 except Exception :
275- _LOGGER .error ('Error fetching splits from storage' )
303+ _LOGGER .error ('Error fetching feature flags from storage' )
276304 _LOGGER .debug ('Error: ' , exc_info = True )
277305 return None
278306
279307 def is_valid_traffic_type (self , traffic_type_name ):
280308 """
281- Return whether the traffic type exists in at least one split in cache.
309+ Return whether the traffic type exists in at least one feature flag in cache.
282310
283311 :param traffic_type_name: Traffic type to validate.
284312 :type traffic_type_name: str
@@ -289,7 +317,7 @@ def is_valid_traffic_type(self, traffic_type_name):
289317 try :
290318 return self .traffic_type_exists (traffic_type_name )
291319 except Exception :
292- _LOGGER .error ('Error getting split info from storage' )
320+ _LOGGER .error ('Error getting traffic type info from storage' )
293321 _LOGGER .debug ('Error: ' , exc_info = True )
294322 return None
295323
0 commit comments