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,77 @@ 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 ._feature_flag_set_prefix .format (flag_set = flag_set ) for flag_set in sets_to_fetch ]
94+ return self ._pluggable_adapter .get_many (keys )
95+ except Exception :
96+ _LOGGER .error ('Error fetching feature flag from storage' )
97+ _LOGGER .debug ('Error: ' , exc_info = True )
98+ return None
99+
100+
74101 # TODO: To be added when producer mode is supported
75102# def put_many(self, splits, change_number):
76103# """
@@ -127,14 +154,14 @@ def update(self, to_add, to_delete, new_change_number):
127154
128155 def get_change_number (self ):
129156 """
130- Retrieve latest split change number.
157+ Retrieve latest feature flag change number.
131158
132159 :rtype: int
133160 """
134161 try :
135- return self ._pluggable_adapter .get (self ._split_till_prefix )
162+ return self ._pluggable_adapter .get (self ._feature_flag_till_prefix )
136163 except Exception :
137- _LOGGER .error ('Error getting change number in split storage' )
164+ _LOGGER .error ('Error getting change number in feature flag storage' )
138165 _LOGGER .debug ('Error: ' , exc_info = True )
139166 return None
140167
@@ -156,35 +183,35 @@ def get_change_number(self):
156183
157184 def get_split_names (self ):
158185 """
159- Retrieve a list of all split names.
186+ Retrieve a list of all feature flag names.
160187
161- :return: List of split names.
188+ :return: List of feature flag names.
162189 :rtype: list(str)
163190 """
164191 try :
165- return [split .name for split in self .get_all ()]
192+ return [feature_flag .name for feature_flag in self .get_all ()]
166193 except Exception :
167- _LOGGER .error ('Error getting split names from storage' )
194+ _LOGGER .error ('Error getting feature flag names from storage' )
168195 _LOGGER .debug ('Error: ' , exc_info = True )
169196 return None
170197
171198 def get_all (self ):
172199 """
173- Return all the splits .
200+ Return all the feature flags .
174201
175- :return: List of all the splits .
202+ :return: List of all the feature flags .
176203 :rtype: list
177204 """
178205 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 ])]
206+ 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 ])]
180207 except Exception :
181- _LOGGER .error ('Error getting split keys from storage' )
208+ _LOGGER .error ('Error getting feature flag keys from storage' )
182209 _LOGGER .debug ('Error: ' , exc_info = True )
183210 return None
184211
185212 def traffic_type_exists (self , traffic_type_name ):
186213 """
187- Return whether the traffic type exists in at least one split in cache.
214+ Return whether the traffic type exists in at least one feature flag in cache.
188215
189216 :param traffic_type_name: Traffic type to validate.
190217 :type traffic_type_name: str
@@ -195,7 +222,7 @@ def traffic_type_exists(self, traffic_type_name):
195222 try :
196223 return self ._pluggable_adapter .get (self ._traffic_type_prefix .format (traffic_type_name = traffic_type_name )) != None
197224 except Exception :
198- _LOGGER .error ('Error getting split info from storage' )
225+ _LOGGER .error ('Error getting traffic type info from storage' )
199226 _LOGGER .debug ('Error: ' , exc_info = True )
200227 return None
201228
@@ -264,21 +291,21 @@ def kill_locally(self, split_name, default_treatment, change_number):
264291
265292 def get_all_splits (self ):
266293 """
267- Return all the splits .
294+ Return all the feature flags .
268295
269- :return: List of all the splits .
296+ :return: List of all the feature flags .
270297 :rtype: list
271298 """
272299 try :
273300 return self .get_all ()
274301 except Exception :
275- _LOGGER .error ('Error fetching splits from storage' )
302+ _LOGGER .error ('Error fetching feature flags from storage' )
276303 _LOGGER .debug ('Error: ' , exc_info = True )
277304 return None
278305
279306 def is_valid_traffic_type (self , traffic_type_name ):
280307 """
281- Return whether the traffic type exists in at least one split in cache.
308+ Return whether the traffic type exists in at least one feature flag in cache.
282309
283310 :param traffic_type_name: Traffic type to validate.
284311 :type traffic_type_name: str
@@ -289,7 +316,7 @@ def is_valid_traffic_type(self, traffic_type_name):
289316 try :
290317 return self .traffic_type_exists (traffic_type_name )
291318 except Exception :
292- _LOGGER .error ('Error getting split info from storage' )
319+ _LOGGER .error ('Error getting traffic type info from storage' )
293320 _LOGGER .debug ('Error: ' , exc_info = True )
294321 return None
295322
0 commit comments