Thanks to visit codestin.com
Credit goes to github.com

Skip to content

updated split api #567

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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
19 changes: 16 additions & 3 deletions splitio/api/splits.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,20 @@ def __init__(self, client, sdk_key, sdk_metadata, telemetry_runtime_producer):
self._spec_version = SPEC_VERSION
self._last_proxy_check_timestamp = 0
self.clear_storage = False
self._old_spec_since = None

def _check_last_proxy_check_timestamp(self):
def _check_last_proxy_check_timestamp(self, since):
if self._spec_version == _SPEC_1_1 and ((utctime_ms() - self._last_proxy_check_timestamp) >= _PROXY_CHECK_INTERVAL_MILLISECONDS_SS):
_LOGGER.info("Switching to new Feature flag spec (%s) and fetching.", SPEC_VERSION);
self._spec_version = SPEC_VERSION
self._old_spec_since = since

def _check_old_spec_since(self, change_number):
if self._spec_version == _SPEC_1_1 and self._old_spec_since is not None:
since = self._old_spec_since
self._old_spec_since = None
return since
return change_number


class SplitsAPI(SplitsAPIBase): # pylint: disable=too-few-public-methods
Expand Down Expand Up @@ -77,7 +86,9 @@ def fetch_splits(self, change_number, rbs_change_number, fetch_options):
:rtype: dict
"""
try:
self._check_last_proxy_check_timestamp()
self._check_last_proxy_check_timestamp(change_number)
change_number = self._check_old_spec_since(change_number)

query, extra_headers = build_fetch(change_number, fetch_options, self._metadata, rbs_change_number)
response = self._client.get(
'sdk',
Expand Down Expand Up @@ -145,7 +156,9 @@ async def fetch_splits(self, change_number, rbs_change_number, fetch_options):
:rtype: dict
"""
try:
self._check_last_proxy_check_timestamp()
self._check_last_proxy_check_timestamp(change_number)
change_number = self._check_old_spec_since(change_number)

query, extra_headers = build_fetch(change_number, fetch_options, self._metadata, rbs_change_number)
response = await self._client.get(
'sdk',
Expand Down
73 changes: 72 additions & 1 deletion tests/api/test_splits_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,41 @@ def get(sdk, splitChanges, sdk_key, extra_headers, query):
assert self.query[2] == {'s': '1.3', 'since': 123, 'rbSince': -1}
assert response == {"ff": {"d": [], "s": 123, "t": 456}, "rbs": {"d": [], "s": 123, "t": -1}}
assert split_api.clear_storage

def test_using_old_spec_since(self, mocker):
"""Test using old_spec_since variable."""
httpclient = mocker.Mock(spec=client.HttpClient)
self.counter = 0
self.query = []
def get(sdk, splitChanges, sdk_key, extra_headers, query):
self.counter += 1
self.query.append(query)
if self.counter == 1:
return client.HttpResponse(400, 'error', {})
if self.counter == 2:
return client.HttpResponse(200, '{"splits": [], "since": 123, "till": 456}', {})
if self.counter == 3:
return client.HttpResponse(400, 'error', {})
if self.counter == 4:
return client.HttpResponse(200, '{"splits": [], "since": 456, "till": 456}', {})

httpclient.is_sdk_endpoint_overridden.return_value = True
httpclient.get = get
split_api = splits.SplitsAPI(httpclient, 'some_api_key', SdkMetadata('1.0', 'some', '1.2.3.4'), mocker.Mock())
response = split_api.fetch_splits(123, -1, FetchOptions(False, None, None, None))
assert response == {"ff": {"d": [], "s": 123, "t": 456}, "rbs": {"d": [], "s": -1, "t": -1}}
assert self.query == [{'s': '1.3', 'since': 123, 'rbSince': -1}, {'s': '1.1', 'since': 123}]
assert not split_api.clear_storage

time.sleep(1)
splits._PROXY_CHECK_INTERVAL_MILLISECONDS_SS = 10

response = split_api.fetch_splits(456, -1, FetchOptions(False, None, None, None))
time.sleep(1)
splits._PROXY_CHECK_INTERVAL_MILLISECONDS_SS = 1000000
assert self.query[2] == {'s': '1.3', 'since': 456, 'rbSince': -1}
assert self.query[3] == {'s': '1.1', 'since': 456}
assert response == {"ff": {"d": [], "s": 456, "t": 456}, "rbs": {"d": [], "s": -1, "t": -1}}

class SplitAPIAsyncTests(object):
"""Split async API test cases."""
Expand Down Expand Up @@ -253,9 +288,45 @@ async def get(sdk, splitChanges, sdk_key, extra_headers, query):
assert self.query == [{'s': '1.3', 'since': 123, 'rbSince': -1}, {'s': '1.1', 'since': 123}]
assert not split_api.clear_storage

time.sleep(1)
time.sleep(1)
splits._PROXY_CHECK_INTERVAL_MILLISECONDS_SS = 10
response = await split_api.fetch_splits(123, -1, FetchOptions(False, None, None, None))
assert self.query[2] == {'s': '1.3', 'since': 123, 'rbSince': -1}
assert response == {"ff": {"d": [], "s": 123, "t": 456}, "rbs": {"d": [], "s": 123, "t": -1}}
assert split_api.clear_storage

@pytest.mark.asyncio
async def test_using_old_spec_since(self, mocker):
"""Test using old_spec_since variable."""
httpclient = mocker.Mock(spec=client.HttpClient)
self.counter = 0
self.query = []
async def get(sdk, splitChanges, sdk_key, extra_headers, query):
self.counter += 1
self.query.append(query)
if self.counter == 1:
return client.HttpResponse(400, 'error', {})
if self.counter == 2:
return client.HttpResponse(200, '{"splits": [], "since": 123, "till": 456}', {})
if self.counter == 3:
return client.HttpResponse(400, 'error', {})
if self.counter == 4:
return client.HttpResponse(200, '{"splits": [], "since": 456, "till": 456}', {})

httpclient.is_sdk_endpoint_overridden.return_value = True
httpclient.get = get
split_api = splits.SplitsAPIAsync(httpclient, 'some_api_key', SdkMetadata('1.0', 'some', '1.2.3.4'), mocker.Mock())
response = await split_api.fetch_splits(123, -1, FetchOptions(False, None, None, None))
assert response == {"ff": {"d": [], "s": 123, "t": 456}, "rbs": {"d": [], "s": -1, "t": -1}}
assert self.query == [{'s': '1.3', 'since': 123, 'rbSince': -1}, {'s': '1.1', 'since': 123}]
assert not split_api.clear_storage

time.sleep(1)
splits._PROXY_CHECK_INTERVAL_MILLISECONDS_SS = 10

response = await split_api.fetch_splits(456, -1, FetchOptions(False, None, None, None))
time.sleep(1)
splits._PROXY_CHECK_INTERVAL_MILLISECONDS_SS = 1000000
assert self.query[2] == {'s': '1.3', 'since': 456, 'rbSince': -1}
assert self.query[3] == {'s': '1.1', 'since': 456}
assert response == {"ff": {"d": [], "s": 456, "t": 456}, "rbs": {"d": [], "s": -1, "t": -1}}