1111from splitio .client .config import sanitize as sanitize_config , DEFAULT_DATA_SAMPLING
1212from splitio .client import util
1313from splitio .client .listener import ImpressionListenerWrapper
14- from splitio .engine .impressions import Manager as ImpressionsManager
14+ from splitio .engine .impressions .impressions import Manager as ImpressionsManager
15+ from splitio .engine .impressions .impressions import ImpressionsMode
16+ from splitio .engine .impressions .manager import Counter as ImpressionsCounter
17+ from splitio .engine .impressions .strategies import StrategyNoneMode , StrategyDebugMode , StrategyOptimizedMode
18+ from splitio .engine .impressions .adapters import InMemorySenderAdapter , RedisSenderAdapter
19+ from splitio .engine .impressions import set_classes
1520
1621# Storage
1722from splitio .storage .inmemmory import InMemorySplitStorage , InMemorySegmentStorage , \
2732from splitio .api .impressions import ImpressionsAPI
2833from splitio .api .events import EventsAPI
2934from splitio .api .auth import AuthAPI
35+ from splitio .api .telemetry import TelemetryAPI
3036
3137# Tasks
3238from splitio .tasks .split_sync import SplitSynchronizationTask
3339from splitio .tasks .segment_sync import SegmentSynchronizationTask
3440from splitio .tasks .impressions_sync import ImpressionsSyncTask , ImpressionsCountSyncTask
3541from splitio .tasks .events_sync import EventsSyncTask
42+ from splitio .tasks .unique_keys_sync import UniqueKeysSyncTask , ClearFilterSyncTask
3643
3744# Synchronizer
3845from splitio .sync .synchronizer import SplitTasks , SplitSynchronizers , Synchronizer , \
39- LocalhostSynchronizer
40- from splitio .sync .manager import Manager
46+ LocalhostSynchronizer , RedisSynchronizer
47+ from splitio .sync .manager import Manager , RedisManager
4148from splitio .sync .split import SplitSynchronizer , LocalSplitSynchronizer
4249from splitio .sync .segment import SegmentSynchronizer
4350from splitio .sync .impression import ImpressionSynchronizer , ImpressionsCountSynchronizer
4451from splitio .sync .event import EventSynchronizer
52+ from splitio .sync .unique_keys import UniqueKeysSynchronizer , ClearFilterSynchronizer
53+
4554
4655# Recorder
4756from splitio .recorder .recorder import StandardRecorder , PipelinedRecorder
@@ -207,6 +216,7 @@ def destroy(self, destroyed_event=None):
207216 return
208217
209218 try :
219+ _LOGGER .info ('Factory destroy called, stopping tasks.' )
210220 if self ._sync_manager is not None :
211221 if destroyed_event is not None :
212222
@@ -283,7 +293,7 @@ def _wrap_impression_listener(listener, metadata):
283293
284294
285295def _build_in_memory_factory (api_key , cfg , sdk_url = None , events_url = None , # pylint:disable=too-many-arguments,too-many-locals
286- auth_api_base_url = None , streaming_api_base_url = None ):
296+ auth_api_base_url = None , streaming_api_base_url = None , telemetry_api_base_url = None ):
287297 """Build and return a split factory tailored to the supplied config."""
288298 if not input_validator .validate_factory_instantiation (api_key ):
289299 return None
@@ -292,6 +302,7 @@ def _build_in_memory_factory(api_key, cfg, sdk_url=None, events_url=None, # pyl
292302 sdk_url = sdk_url ,
293303 events_url = events_url ,
294304 auth_url = auth_api_base_url ,
305+ telemetry_url = telemetry_api_base_url ,
295306 timeout = cfg .get ('connectionTimeout' )
296307 )
297308
@@ -302,6 +313,7 @@ def _build_in_memory_factory(api_key, cfg, sdk_url=None, events_url=None, # pyl
302313 'segments' : SegmentsAPI (http_client , api_key , sdk_metadata ),
303314 'impressions' : ImpressionsAPI (http_client , api_key , sdk_metadata , cfg ['impressionsMode' ]),
304315 'events' : EventsAPI (http_client , api_key , sdk_metadata ),
316+ 'telemetry' : TelemetryAPI (http_client , api_key , sdk_metadata ),
305317 }
306318
307319 if not input_validator .validate_apikey_type (apis ['segments' ]):
@@ -314,18 +326,23 @@ def _build_in_memory_factory(api_key, cfg, sdk_url=None, events_url=None, # pyl
314326 'events' : InMemoryEventStorage (cfg ['eventsQueueSize' ]),
315327 }
316328
329+ unique_keys_synchronizer , clear_filter_sync , unique_keys_task , \
330+ clear_filter_task , impressions_count_sync , impressions_count_task , \
331+ imp_strategy = set_classes ('MEMORY' , cfg ['impressionsMode' ], apis )
332+
317333 imp_manager = ImpressionsManager (
318- cfg ['impressionsMode' ],
319- True ,
320- _wrap_impression_listener (cfg ['impressionListener' ], sdk_metadata ))
334+ _wrap_impression_listener (cfg ['impressionListener' ], sdk_metadata ),
335+ imp_strategy )
321336
322337 synchronizers = SplitSynchronizers (
323338 SplitSynchronizer (apis ['splits' ], storages ['splits' ]),
324339 SegmentSynchronizer (apis ['segments' ], storages ['splits' ], storages ['segments' ]),
325340 ImpressionSynchronizer (apis ['impressions' ], storages ['impressions' ],
326341 cfg ['impressionsBulkSize' ]),
327342 EventSynchronizer (apis ['events' ], storages ['events' ], cfg ['eventsBulkSize' ]),
328- ImpressionsCountSynchronizer (apis ['impressions' ], imp_manager ),
343+ impressions_count_sync ,
344+ unique_keys_synchronizer ,
345+ clear_filter_sync
329346 )
330347
331348 tasks = SplitTasks (
@@ -342,7 +359,9 @@ def _build_in_memory_factory(api_key, cfg, sdk_url=None, events_url=None, # pyl
342359 cfg ['impressionsRefreshRate' ],
343360 ),
344361 EventsSyncTask (synchronizers .events_sync .synchronize_events , cfg ['eventsPushRate' ]),
345- ImpressionsCountSyncTask (synchronizers .impressions_count_sync .synchronize_counters )
362+ impressions_count_task ,
363+ unique_keys_task ,
364+ clear_filter_task
346365 )
347366
348367 synchronizer = Synchronizer (synchronizers , tasks )
@@ -393,19 +412,47 @@ def _build_redis_factory(api_key, cfg):
393412 _LOGGER .warning ("dataSampling cannot be less than %.2f, defaulting to minimum" ,
394413 _MIN_DEFAULT_DATA_SAMPLING_ALLOWED )
395414 data_sampling = _MIN_DEFAULT_DATA_SAMPLING_ALLOWED
415+
416+ unique_keys_synchronizer , clear_filter_sync , unique_keys_task , \
417+ clear_filter_task , impressions_count_sync , impressions_count_task , \
418+ imp_strategy = set_classes ('REDIS' , cfg ['impressionsMode' ], redis_adapter )
419+
420+ imp_manager = ImpressionsManager (
421+ _wrap_impression_listener (cfg ['impressionListener' ], sdk_metadata ),
422+ imp_strategy )
423+
424+ synchronizers = SplitSynchronizers (None , None , None , None ,
425+ impressions_count_sync ,
426+ unique_keys_synchronizer ,
427+ clear_filter_sync
428+ )
429+
430+ tasks = SplitTasks (None , None , None , None ,
431+ impressions_count_task ,
432+ unique_keys_task ,
433+ clear_filter_task
434+ )
435+
436+ synchronizer = RedisSynchronizer (synchronizers , tasks )
396437 recorder = PipelinedRecorder (
397438 redis_adapter .pipeline ,
398- ImpressionsManager (cfg ['impressionsMode' ], False ,
399- _wrap_impression_listener (cfg ['impressionListener' ], sdk_metadata )),
439+ imp_manager ,
400440 storages ['events' ],
401441 storages ['impressions' ],
402442 data_sampling ,
403443 )
444+
445+ manager = RedisManager (synchronizer )
446+ initialization_thread = threading .Thread (target = manager .start , name = "SDKInitializer" )
447+ initialization_thread .setDaemon (True )
448+ initialization_thread .start ()
449+
404450 return SplitFactory (
405451 api_key ,
406452 storages ,
407453 cfg ['labelsEnabled' ],
408454 recorder ,
455+ manager ,
409456 )
410457
411458
@@ -436,7 +483,7 @@ def _build_localhost_factory(cfg):
436483 manager = Manager (ready_event , synchronizer , None , False , sdk_metadata )
437484 manager .start ()
438485 recorder = StandardRecorder (
439- ImpressionsManager (cfg [ 'impressionsMode' ], True , None ),
486+ ImpressionsManager (None , StrategyDebugMode () ),
440487 storages ['events' ],
441488 storages ['impressions' ],
442489 )
@@ -485,7 +532,8 @@ def get_factory(api_key, **kwargs):
485532 kwargs .get ('sdk_api_base_url' ),
486533 kwargs .get ('events_api_base_url' ),
487534 kwargs .get ('auth_api_base_url' ),
488- kwargs .get ('streaming_api_base_url' )
535+ kwargs .get ('streaming_api_base_url' ),
536+ kwargs .get ('telemetry_api_base_url' )
489537 )
490538 finally :
491539 _INSTANTIATED_FACTORIES .update ([api_key ])
0 commit comments