Skip to content

Commit ff8c2ff

Browse files
committed
Refactor strategies, filters and adapters, and updated tests
1 parent 74e5565 commit ff8c2ff

24 files changed

+177
-198
lines changed

splitio/client/factory.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,9 @@
1313
from splitio.client.listener import ImpressionListenerWrapper
1414
from splitio.engine.impressions import Manager as ImpressionsManager
1515
from splitio.engine.impressions import ImpressionsMode
16-
from splitio.engine.strategies import Counter as ImpressionsCounter
17-
from splitio.engine.strategies.strategy_debug_mode import StrategyDebugMode
18-
from splitio.engine.strategies.strategy_optimized_mode import StrategyOptimizedMode
19-
from splitio.engine.strategies.strategy_none_mode import StrategyNoneMode
20-
from splitio.engine.sender_adapters.in_memory_sender_adapter import InMemorySenderAdapter
16+
from splitio.engine.manager import Counter as ImpressionsCounter
17+
from splitio.engine.strategies import StrategyNoneMode, StrategyDebugMode, StrategyOptimizedMode
18+
from splitio.engine.adapters import InMemorySenderAdapter
2119

2220
# Storage
2321
from splitio.storage.inmemmory import InMemorySplitStorage, InMemorySegmentStorage, \
@@ -333,11 +331,11 @@ def _build_in_memory_factory(api_key, cfg, sdk_url=None, events_url=None, # pyl
333331
clear_filter_task = None
334332
if cfg['impressionsMode'] == ImpressionsMode.NONE:
335333
imp_strategy = StrategyNoneMode(imp_counter)
336-
clear_filter_sync = ClearFilterSynchronizer(imp_strategy._unique_keys_tracker)
337-
unique_keys_synchronizer = UniqueKeysSynchronizer(InMemorySenderAdapter(apis['telemetry']), imp_strategy._unique_keys_tracker)
334+
clear_filter_sync = ClearFilterSynchronizer(imp_strategy.get_unique_keys_tracker())
335+
unique_keys_synchronizer = UniqueKeysSynchronizer(InMemorySenderAdapter(apis['telemetry']), imp_strategy.get_unique_keys_tracker())
338336
unique_keys_task = UniqueKeysSyncTask(unique_keys_synchronizer.send_all)
339337
clear_filter_task = ClearFilterSyncTask(clear_filter_sync.clear_all)
340-
imp_strategy._unique_keys_tracker.set_queue_full_hook(unique_keys_task.flush)
338+
imp_strategy.get_unique_keys_tracker().set_queue_full_hook(unique_keys_task.flush)
341339
elif cfg['impressionsMode'] == ImpressionsMode.DEBUG:
342340
imp_strategy = StrategyDebugMode()
343341
else:

splitio/engine/sender_adapters/in_memory_sender_adapter.py renamed to splitio/engine/adapters.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
1+
import abc
12
import json
23

3-
from splitio.engine.sender_adapters import ImpressionsSenderAdapter
4+
5+
class ImpressionsSenderAdapter(object, metaclass=abc.ABCMeta):
6+
"""Impressions Sender Adapter interface."""
7+
8+
@abc.abstractmethod
9+
def record_unique_keys(self, data):
10+
"""
11+
No Return value
12+
13+
"""
14+
pass
415

516
class InMemorySenderAdapter(ImpressionsSenderAdapter):
617
"""In Memory Impressions Sender Adapter class."""
@@ -33,9 +44,6 @@ def _uniques_formatter(self, uniques):
3344
:return: unique keys JSON
3445
:rtype: json
3546
"""
36-
if len(uniques) == 0:
37-
return json.loads('{"keys": []}')
38-
3947
return {
4048
'keys': [{'f': feature, 'ks': list(keys)} for feature, keys in uniques.items()]
4149
}
Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,34 @@
1-
from splitio.engine.filters import BaseFilter
1+
import abc
2+
23
from bloom_filter2 import BloomFilter as BloomFilter2
34

5+
class BaseFilter(object, metaclass=abc.ABCMeta):
6+
"""Impressions Filter interface."""
7+
8+
@abc.abstractmethod
9+
def add(self, data):
10+
"""
11+
Return a boolean flag
12+
13+
"""
14+
pass
15+
16+
@abc.abstractmethod
17+
def contains(self, data):
18+
"""
19+
Return a boolean flag
20+
21+
"""
22+
pass
23+
24+
@abc.abstractmethod
25+
def clear(self):
26+
"""
27+
No return
28+
29+
"""
30+
pass
31+
432
class BloomFilter(BaseFilter):
533
"""Optimized mode strategy."""
634

splitio/engine/filters/__init__.py

Lines changed: 0 additions & 28 deletions
This file was deleted.

splitio/engine/sender_adapters/__init__.py

Lines changed: 0 additions & 12 deletions
This file was deleted.

splitio/engine/strategies.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import abc
2+
3+
from splitio.engine.manager import Observer, truncate_impressions_time, Counter, truncate_time
4+
from splitio.engine.unique_keys_tracker import UniqueKeysTracker
5+
from splitio import util
6+
7+
_IMPRESSION_OBSERVER_CACHE_SIZE = 500000
8+
_UNIQUE_KEYS_CACHE_SIZE = 30000
9+
10+
class BaseStrategy(object, metaclass=abc.ABCMeta):
11+
"""Strategy interface."""
12+
13+
@abc.abstractmethod
14+
def process_impressions(self):
15+
"""
16+
Return a list(impressions) object
17+
18+
"""
19+
pass
20+
21+
class StrategyDebugMode(BaseStrategy):
22+
"""Debug mode strategy."""
23+
24+
def __init__(self):
25+
"""
26+
Construct a strategy instance for debug mode.
27+
28+
"""
29+
self._observer = Observer(_IMPRESSION_OBSERVER_CACHE_SIZE)
30+
31+
def process_impressions(self, impressions):
32+
"""
33+
Process impressions.
34+
35+
Impressions are analyzed to see if they've been seen before.
36+
37+
:param impressions: List of impression objects with attributes
38+
:type impressions: list[tuple[splitio.models.impression.Impression, dict]]
39+
40+
:returns: Observed list of impressions
41+
:rtype: list[tuple[splitio.models.impression.Impression, dict]]
42+
"""
43+
imps = [(self._observer.test_and_set(imp), attrs) for imp, attrs in impressions]
44+
return [i for i, _ in imps], imps
45+
46+
class StrategyNoneMode(BaseStrategy):
47+
"""Debug mode strategy."""
48+
49+
def __init__(self, counter):
50+
"""
51+
Construct a strategy instance for none mode.
52+
53+
"""
54+
self._counter = counter
55+
self._unique_keys_tracker = UniqueKeysTracker(_UNIQUE_KEYS_CACHE_SIZE)
56+
57+
def process_impressions(self, impressions):
58+
"""
59+
Process impressions.
60+
61+
Impressions are analyzed to see if they've been seen before and counted.
62+
Unique keys tracking are updated.
63+
64+
:param impressions: List of impression objects with attributes
65+
:type impressions: list[tuple[splitio.models.impression.Impression, dict]]
66+
67+
:returns: Empty list, no impressions to post
68+
:rtype: list[]
69+
"""
70+
self._counter.track([imp for imp, _ in impressions])
71+
for i, _ in impressions:
72+
self._unique_keys_tracker.track(i.matching_key, i.feature_name)
73+
return [], impressions
74+
75+
def get_unique_keys_tracker(self):
76+
return self._unique_keys_tracker
77+
78+
class StrategyOptimizedMode(BaseStrategy):
79+
"""Optimized mode strategy."""
80+
81+
def __init__(self, counter):
82+
"""
83+
Construct a strategy instance for optimized mode.
84+
85+
"""
86+
self._observer = Observer(_IMPRESSION_OBSERVER_CACHE_SIZE)
87+
self._counter = counter
88+
89+
def process_impressions(self, impressions):
90+
"""
91+
Process impressions.
92+
93+
Impressions are analyzed to see if they've been seen before and counted.
94+
95+
:param impressions: List of impression objects with attributes
96+
:type impressions: list[tuple[splitio.models.impression.Impression, dict]]
97+
98+
:returns: Observed list of impressions
99+
:rtype: list[tuple[splitio.models.impression.Impression, dict]]
100+
"""
101+
imps = [(self._observer.test_and_set(imp), attrs) for imp, attrs in impressions]
102+
self._counter.track([imp for imp, _ in imps])
103+
this_hour = truncate_time(util.utctime_ms())
104+
return [i for i, _ in imps if i.previous_time is None or i.previous_time < this_hour], imps

splitio/engine/strategies/base_strategy.py

Lines changed: 0 additions & 12 deletions
This file was deleted.

splitio/engine/strategies/strategy_debug_mode.py

Lines changed: 0 additions & 29 deletions
This file was deleted.

splitio/engine/strategies/strategy_none_mode.py

Lines changed: 0 additions & 35 deletions
This file was deleted.

0 commit comments

Comments
 (0)