Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
added models, events config data and events metadata
  • Loading branch information
chillaq committed Jan 7, 2026
commit c65fd014fa7d971e50c1ac6c5da81ddb91aaddc7
Empty file added splitio/events/__init__.py
Empty file.
124 changes: 124 additions & 0 deletions splitio/events/events_manager_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
"""Events Manager Configuration."""
from splitio.models.events import SdkEvent, SdkInternalEvent

class EventsManagerConfig(object):
"""Events Manager Configurations class."""

def __init__(self):
"""
Construct Events Manager Configuration instance.
"""
self._require_all = self._get_require_all()
self._prerequisites = self._get_prerequisites()
self._require_any = self._get_require_any()
self._suppressed_by = self._get_suppressed_by()
self._execution_limits = self._get_execution_limits()
self._evaluation_order = self._get_sorted_events()

@property
def require_all(self):
"""Return require all dict"""
return self._require_all

@property
def prerequisites(self):
"""Return prerequisites dict"""
return self._prerequisites

@property
def require_any(self):
"""Return require_any dict"""
return self._require_any

@property
def suppressed_by(self):
"""Return suppressed_by dict"""
return self._suppressed_by

@property
def execution_limits(self):
"""Return execution_limits dict"""
return self._execution_limits

@property
def prerequisites(self):
"""Return require all dict"""
return self._prerequisites
Comment thread
chillaq marked this conversation as resolved.
Outdated

@property
def evaluation_order(self):
"""Return evaluation_order dict"""
return self._evaluation_order

@property
def sorted_events(self):
"""Return sorted_events dict"""
return self._sorted_events

def _get_require_all(self):
"""Return require all dict"""
return {
SdkEvent.SDK_READY: {SdkInternalEvent.SDK_READY}
}

def _get_prerequisites(self):
"""Return prerequisites dict"""
return {
SdkEvent.SDK_UPDATE: {SdkEvent.SDK_READY}
}

def _get_require_any(self):
"""Return require_any dict"""
return {
SdkEvent.SDK_UPDATE: {SdkInternalEvent.FLAG_KILLED_NOTIFICATION, SdkInternalEvent.FLAGS_UPDATED,
SdkInternalEvent.RB_SEGMENTS_UPDATED, SdkInternalEvent.SEGMENTS_UPDATED},
SdkEvent.SDK_READY_TIMED_OUT: {SdkInternalEvent.SDK_TIMED_OUT}
}

def _get_suppressed_by(self):
"""Return suppressed_by dict"""
return {
SdkEvent.SDK_READY_TIMED_OUT: {SdkEvent.SDK_READY}
}

def _get_execution_limits(self):
"""Return execution_limits dict"""
return {
SdkEvent.SDK_READY: 1,
SdkEvent.SDK_READY_TIMED_OUT: -1,
SdkEvent.SDK_UPDATE: -1
}

def _get_sorted_events(self):
"""Return dorted events set"""
sorted_events = []
for sdk_event in [SdkEvent.SDK_READY, SdkEvent.SDK_READY_TIMED_OUT, SdkEvent.SDK_UPDATE]:
sorted_events = self._dfs_recursive(sdk_event, sorted_events)

return sorted_events


def _dfs_recursive(self, sdk_event, added):
"""Return sorted events set based on the dependency rules"""
if sdk_event in added:
return added

for dependent_event in self._get_dependencies(sdk_event):
added = self._dfs_recursive(dependent_event, added)

added.append(sdk_event)
return added

def _get_dependencies(self, sdk_event):
"""Return dependencies set from prerequisites and suppressed events for a given event"""
dependencies = set()
for prerequisites_event_name, prerequisites_event_value in self.prerequisites.items():
if prerequisites_event_name == sdk_event:
for prereq_event in prerequisites_event_value:
dependencies.add(prereq_event)

for suppressed_event_name, suppressed_event_value in self.suppressed_by.items():
if sdk_event in suppressed_event_value:
dependencies.add(suppressed_event_name)

return dependencies
46 changes: 46 additions & 0 deletions splitio/events/events_metadata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""Events Metadata."""
from splitio.models.events import SdkEvent, SdkInternalEvent

class EventsMetadata(object):
"""Events Metadata class."""

def __init__(self, metadata):
"""
Construct Events Metadata instance.
"""
self._metadata = self._sanitize(metadata)

def get_data(self):
"""Return metadata dict"""
return self._metadata

def get_keys(self):
"""Return metadata dict keys"""
return self._metadata.keys()

def get_values(self):
"""Return metadata dict values"""
return self._metadata.values()

def contain_key(self, key):
"""Return True if key is contained in metadata"""
return key in self._metadata.keys()

def _sanitize(self, data):
"""Return sanitized metadata dict with values either int, bool, str or list """
santized_data = {}
for item_name, item_value in data.items():
if self._value_is_valid(item_value):
santized_data[item_name] = item_value

return santized_data

def _value_is_valid(self, value):
"""Return bool if values is int, bool, str or list[str] """
if (value is not None) and (isinstance(value, int) or isinstance(value, bool) or isinstance(value, str)):
return True

if isinstance(value, set):
return any([isinstance(item, str) for item in value])

return False
22 changes: 21 additions & 1 deletion splitio/models/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
The dto is implemented as a namedtuple for performance matters.
"""
from collections import namedtuple

from enum import Enum

Event = namedtuple('Event', [
'key',
Expand All @@ -19,3 +19,23 @@
'event',
'size',
])

class SdkEvent(Enum):
"""Public SDK events"""

SDK_READY = 'SDK_READY'
SDK_READY_TIMED_OUT = 'SDK_READY_TIMED_OUT'
SDK_UPDATE = 'SDK_UPDATE'

class SdkInternalEvent(Enum):
"""Internal SDK events"""

SDK_READY = 'SDK_READY'
SDK_TIMED_OUT = 'SDK_TIMED_OUT'
FLAGS_UPDATED = 'FLAGS_UPDATED'
FLAG_KILLED_NOTIFICATION = 'FLAG_KILLED_NOTIFICATION'
SEGMENTS_UPDATED = 'SEGMENTS_UPDATED'
RB_SEGMENTS_UPDATED = 'RB_SEGMENTS_UPDATED'
LARGE_SEGMENTS_UPDATED = 'LARGE_SEGMENTS_UPDATED'


43 changes: 43 additions & 0 deletions tests/events/test_events_manager_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""EventsManagerConfig test module."""
import pytest

from splitio.events.events_manager_config import EventsManagerConfig
from splitio.models.events import SdkEvent, SdkInternalEvent

class EventsManagerConfigTests(object):
"""Tests for EventsManagerConfig."""

def test_build_instance(self):
config = EventsManagerConfig()

assert len(config.require_all[SdkEvent.SDK_READY]) == 1
assert SdkInternalEvent.SDK_READY in config.require_all[SdkEvent.SDK_READY]

assert SdkEvent.SDK_READY in config.prerequisites[SdkEvent.SDK_UPDATE]

assert config.execution_limits[SdkEvent.SDK_READY_TIMED_OUT] == -1
assert config.execution_limits[SdkEvent.SDK_UPDATE] == -1
assert config.execution_limits[SdkEvent.SDK_READY] == 1

assert len(config.require_any[SdkEvent.SDK_READY_TIMED_OUT]) == 1
assert SdkInternalEvent.SDK_TIMED_OUT in config.require_any[SdkEvent.SDK_READY_TIMED_OUT]

assert len(config.require_any[SdkEvent.SDK_UPDATE]) == 4
assert SdkInternalEvent.FLAG_KILLED_NOTIFICATION in config.require_any[SdkEvent.SDK_UPDATE]
assert SdkInternalEvent.FLAGS_UPDATED in config.require_any[SdkEvent.SDK_UPDATE]
assert SdkInternalEvent.RB_SEGMENTS_UPDATED in config.require_any[SdkEvent.SDK_UPDATE]
assert SdkInternalEvent.SEGMENTS_UPDATED in config.require_any[SdkEvent.SDK_UPDATE]

assert len(config.suppressed_by[SdkEvent.SDK_READY_TIMED_OUT]) == 1
assert SdkEvent.SDK_READY in config.suppressed_by[SdkEvent.SDK_READY_TIMED_OUT]

order = 0
assert len(config.evaluation_order) == 3
for sdk_event in config.evaluation_order:
order += 1
if order == 1:
assert sdk_event == SdkEvent.SDK_READY_TIMED_OUT
if order == 2:
assert sdk_event == SdkEvent.SDK_READY
if order == 3:
assert sdk_event == SdkEvent.SDK_UPDATE
28 changes: 28 additions & 0 deletions tests/events/test_events_metadata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""EventsMetadata test module."""
import pytest

from splitio.events.events_metadata import EventsMetadata
from splitio.models.events import SdkEvent, SdkInternalEvent

class EventsMetadataTests(object):
"""Tests for EventsMetadata."""

def test_build_instance(self):
data = { "updatedFlags": { "feature1" }, "sdkTimeout": 10 , "boolValue": True, "strValue": "value" }
metadata = EventsMetadata(data)

assert len(metadata.get_keys()) == 4
assert metadata.get_data()["updatedFlags"].pop() == "feature1"
assert len(metadata.get_data()["updatedFlags"]) == 0
assert metadata.get_data()["sdkTimeout"] == 10
assert metadata.get_data()["boolValue"] == True
assert metadata.get_data()["strValue"] == "value"
assert metadata.contain_key("updatedFlags")
assert not metadata.contain_key("not_exist")
assert len(metadata.get_values()) == 4

def test_sanitize_none_input(self):
data = { "updatedFlags": { "feature1" }, "sdkTimeout": None, "strValue": [1, 2, 3] }
metadata = EventsMetadata(data)
assert len(metadata.get_keys()) == 1
assert metadata.get_data()["updatedFlags"].pop() == "feature1"